HarmonyOS鸿蒙Next中实现小艺输入法的键盘区域外显示的按键序列效果

HarmonyOS鸿蒙Next中实现小艺输入法的键盘区域外显示的按键序列效果 【问题描述】:需要实现类似小艺输入法的效果

【问题现象】:

cke_603.png

【版本信息】:不涉及

【复现代码】:不涉及

【尝试解决方案】:不涉及


更多关于HarmonyOS鸿蒙Next中实现小艺输入法的键盘区域外显示的按键序列效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

【解决方案】

开发者你好

1、当输入法采用单面板设计时,可以通过固定键盘高度来预留顶部候选词区域,但由于系统限制,非系统级输入法应用无法在键盘区域之外创建或显示内容。

2、如果想要实现键盘区域外显示内容,可采用以下两种方案:

(1)多面板协同显示:在原有输入法面板基础上,额外创建一个STATUS_BAR类型的面板。通过这种方式,实现固定态软键盘面板与STATUS_BAR类型面板的共存,使候选词区域可以独立显示在键盘区域之外。

(2)全屏热区控制:利用键盘窗口的adjustPanelRect接口将键盘设置为全屏模式,通过控制热区,来改变键盘响应区域,这样的话不受面板大小限制,可在任意位置自定义UI页面。

更多关于HarmonyOS鸿蒙Next中实现小艺输入法的键盘区域外显示的按键序列效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


试了一下改低输入法的高度,还是会自动顶上去,不过可以把拼音预上屏打开,拼音就会在输入框里,不会遮挡到了。

cke_2000.jpeg

cke_2228.jpeg

可以向微信客服反馈一下

在HarmonyOS Next中,可通过TextInput组件配合onKeyEvent监听键盘事件,获取按键序列。使用KeyEvent对象解析按键码,转换为对应字符并存储。通过自定义组件(如RowFlex)在键盘区域外显示按键序列。示例代码片段如下:

@State keySequence: string = '';

TextInput()
  .onKeyEvent((event: KeyEvent) => {
    if (event.type === KeyType.Down) {
      this.keySequence += KeyCode[event.keyCode];
    }
  })

// 显示区域
Text(this.keySequence)

需在onKeyEvent中处理按键逻辑,确保仅响应按下事件。

在HarmonyOS Next中实现键盘区域外显示的按键序列效果,核心在于使用Overlay组件和自定义弹窗。

主要实现思路如下:

  1. 监听按键事件:在输入法键盘的按键组件(如Button)上,通过手势事件(如onTouch)监听用户的按下(TouchType.Down)和移动(TouchType.Move)动作。
  2. 计算悬浮位置:在触发事件时,获取触摸点的全局坐标(通过getLocationOnScreen等方法),并以此坐标为基础,向上偏移一定距离,作为悬浮窗的显示位置。
  3. 使用Overlay显示悬浮窗
    • aboutToAppear生命周期或页面入口处,通过window.getLastWindow(this.context)获取窗口对象。
    • 调用窗口对象的windowClass.loadContent方法,加载一个自定义的弹窗组件。这个弹窗组件就是你希望显示的按键序列或放大镜效果。
    • 弹窗组件应使用@CustomDialog装饰器定义,并设置为无边框、透明背景。其内容通常是一个Text组件,用于显示按下的键(如“q”、“w”、“e”等),并应用放大和阴影等样式。
  4. 控制显示与隐藏
    • TouchType.DownTouchType.Move时,更新弹窗的内容(按键文本)和位置,并显示弹窗。
    • TouchType.UpTouchType.Cancel(手指抬起或取消)时,关闭或隐藏弹窗。

关键代码示例(ArkTS):

// 1. 在按键组件上监听触摸事件
Button("Q")
  .onTouch((event: TouchEvent) => {
    if (event.type === TouchType.Down || event.type === TouchType.Move) {
      // 获取触摸点全局位置
      let globalX = ...;
      let globalY = ...;
      // 计算弹窗显示位置(例如在触摸点上方)
      let popupX = globalX;
      let popupY = globalY - 100; // 向上偏移100vp
      // 显示自定义弹窗,并传递位置和按键内容
      showKeyPopup({ x: popupX, y: popupY }, "Q");
    }
    if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
      // 隐藏弹窗
      hideKeyPopup();
    }
  })

// 2. 定义并管理自定义弹窗(Overlay)
// 使用@CustomDialog定义弹窗组件
@CustomDialog
struct KeyPopupDialog {
  // 弹窗内容,接收位置和文本参数
  @Link text: string;
  @Link position: { x: number, y: number };

  build() {
    Column() {
      Text(this.text)
        .fontSize(30)
        .fontColor(Color.White)
        .backgroundColor(Color.Gray)
        .padding(10)
        .borderRadius(10)
        .shadow({ radius: 10, color: Color.Black })
    }
    .position({ x: this.position.x, y: this.position.y })
    .backgroundColor(Color.Transparent) // 透明背景
  }
}

// 在页面中管理弹窗的显示/隐藏
private dialogController: CustomDialogController = new CustomDialogController({
  builder: KeyPopupDialog({ /* 初始化参数 */ }),
  alignment: DialogAlignment.Default, // 使用自定义位置,此设置可能被覆盖
  customStyle: true // 启用自定义样式
});

// 显示弹窗的函数
showKeyPopup(position: { x: number, y: number }, keyText: string) {
  // 更新弹窗参数
  // 注意:这里需要一种方式将位置和文本传递给弹窗,可以通过@Link、@Prop或构造函数参数实现。
  // 然后打开弹窗
  this.dialogController.open();
}

hideKeyPopup() {
  this.dialogController.close();
}

注意事项:

  • 性能:频繁调用loadContent或更新Overlay可能影响性能。建议复用同一个Overlay节点,通过状态变量控制其内容和位置的更新。
  • 精准定位:确保获取的触摸点坐标是相对于屏幕全局的,并且弹窗的定位方式(如position)与之匹配。
  • 手势冲突:注意避免与输入法其他区域的手势产生冲突。
  • 多指触摸:根据需求处理多指触摸场景,通常输入法按键只响应单指。

这种实现方式利用了HarmonyOS Next的UI自定义能力和Overlay的灵活布局,可以达到与小艺输入法类似的视觉反馈效果。

回到顶部