HarmonyOS鸿蒙Next中怎么处理自定义键盘编辑输入的时候光标乱跳的问题

HarmonyOS鸿蒙Next中怎么处理自定义键盘编辑输入的时候光标乱跳的问题

【问题现象】

从自定义键盘切换到系统键盘,光标总是移动到最后。自定义键盘通过onchange事件监听光标位置变化,关键代码如下:

@Entry
@Component
struct TextInputExample {
  controller: TextInputController = new TextInputController();
  [@State](/user/State) text: string = "";
  [@State](/user/State) ep: number = 0;
  [@State](/user/State) del: boolean = false;
  [@State](/user/State) keyboardType: number = 0;

  // 自定义键盘组件
  @Builder
  buildCustomKeyboard() {
    Column() {
      Button('删除').onClick(() => {
        this.text = this.text.substring(0, this.ep - 1) + this.text.substring(this.ep);
        this.del = true;
      })
      Grid() {
        ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '# '], (item: number | string) => {
          GridItem() {
            Button(item + "")
              .width(110).onClick(() => {
              this.text = this.text.substring(0, this.ep) + item + this.text.substring(this.ep);
              this.del = false;
            })
          }
        })
      }.maxCount(3).columnsGap(10).rowsGap(10).padding(5)
    }.backgroundColor(Color.Gray)
  }

  build() {
    Column() {
      TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
        .customKeyboard(this.keyboardType == 0 ? this.buildCustomKeyboard() : null) // 系统键盘和自定义键盘切换
        .placeholderFont({ size: 14, weight: 400 })
        .width(320)
        .height(40)
        .fontSize(14)
        .fontColor(Color.Black)
        .backgroundColor('rgba(0,0,0,0.1)')
        .id('TextInput') // 感知光标的变化,然后调整光标位置
        .onChange(() => {
          if (this.del) {
            this.controller.caretPosition(--this.ep)
          } else {
            this.controller.caretPosition(++this.ep)
          }
        })
        .onTextSelectionChange((ss) => {
          this.ep = ss;
        })
    }
  }
}

【背景知识】

  • TextInput设置自定义键盘:通过TextInput的customKeyboard属性来设置自定义键盘。
  • 自定义键盘和系统键盘切换:可以通过@State声明一个状态变量,动态控制customKeyboard属性的值来实现自定义键盘和系统键盘的切换。

【定位思路】

光标总是移动到最后,是因为切换键盘做了事件注入,会在onchange事件中监听光标位置的变化。因此在切换键盘时需要先通过requestfocus转移焦点来避免光标位置错误。

【解决方案】

TextInput组件:

TextInput的focusable属性控制输入框是否可聚焦。

TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller })
  .id('TextInput')
  .customKeyboard(this.keyboardType == 0 ? this.buildCustomKeyboard() : null) // 系统键盘和自定义键盘切换
  .defaultFocus(true)
  .focusable(this.flag) // 是否可聚焦

自定义键盘:

包含了600、800 两个输入项。

@Builder
buildCustomKeyboard() {
  Column({ space: 10 }) {
    Row({ space: 10 }) {
      Text('600').width('50%').textAlign(TextAlign.Center)
        .onClick(() => {
          this.text = '600'
        })
      Text('800').width('50%').textAlign(TextAlign.Center)
        .onClick(() => {
          this.text = '800'
        })
    }
    .justifyContent(FlexAlign.SpaceAround)
    .width('100%')
    .layoutWeight(1)

    Row({ space: 10 }) {
      Text('确认')
        .onClick(() => {
          this.controller.stopEditing() // 关闭自定义键盘
        })
    }
    .justifyContent(FlexAlign.SpaceAround)
    .width('100%')
    .layoutWeight(1)
  }
  .backgroundColor('rgba(0,0,0,0.1)')
  .height(200)
}

切换键盘方法:

设置输入框不可获取焦点,延后一段时间设置输入框可获取焦点,并调用requestFocus方法使输入框TextInput取得焦点。

switchKeyBoard(keyboardType:number){
  this.keyboardType = keyboardType;
  this.flag = false; // 设置输入框不可聚焦,调出系统键盘
  setTimeout(() => {
    this.flag = true; // 设置输入框可聚焦
    focusControl.requestFocus('TextInput'); // 输入框获取焦点
  }, 300)
}

代码示例如下:

@Entry
@Component
struct Index {
  [@State](/user/State) keyboardType: number = 0
  [@State](/user/State) text: string = ''
  controller: TextInputController = new TextInputController()
  [@State](/user/State) flag: boolean = true
  build() {
    Column({ space: 10 }) {
      TextInput({ text: $$this.text, placeholder: 'input your word...', controller: this.controller })
        .placeholderFont({ size: 14, weight: 400 })
        .width(320)
        .height(40)
        .fontSize(14)
        .fontColor(Color.Black)
        .backgroundColor('rgba(0,0,0,0.1)')
        .id('TextInput')
        .customKeyboard(this.keyboardType == 0 ? this.buildCustomKeyboard() : null)  // 系统键盘和自定义键盘切换
        .defaultFocus(true)
        .focusable(this.flag)  // 是否可聚焦

      Button('切换系统键盘')
        .onClick(() => {
          this.switchKeyBoard(1);  // 调出系统键盘
        })
      Button('切换自定义键盘')
        .onClick(() => {
          this.switchKeyBoard(0);  // 调出自定义键盘
        })
    }
    .backgroundColor(Color.White)
    .expandSafeArea([SafeAreaType.SYSTEM])
    .width('100%')
    .height('100%')
  }
}

效果截图:

效果截图


更多关于HarmonyOS鸿蒙Next中怎么处理自定义键盘编辑输入的时候光标乱跳的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中怎么处理自定义键盘编辑输入的时候光标乱跳的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中处理自定义键盘编辑输入时光标乱跳的问题

在HarmonyOS鸿蒙Next中处理自定义键盘编辑输入时光标乱跳的问题,可以通过以下步骤解决:

  1. 设置输入框不可聚焦:在切换键盘时,先将输入框的focusable属性设置为false,避免光标位置错误。
  2. 延迟设置输入框可聚焦:使用setTimeout延迟一段时间后,再将focusable属性设置为true
  3. 请求焦点:调用requestFocus方法使输入框重新获取焦点。

示例代码如下:

switchKeyBoard(keyboardType: number) {
  this.keyboardType = keyboardType;
  this.flag = false; // 设置输入框不可聚焦,调出系统键盘
  setTimeout(() => {
    this.flag = true; // 设置输入框可聚焦
    focusControl.requestFocus('TextInput'); // 输入框获取焦点
  }, 300);
}

通过以上步骤,可以在切换键盘时避免光标乱跳的问题。

回到顶部