HarmonyOS鸿蒙Next中textInput的previewText为空

HarmonyOS鸿蒙Next中textInput的previewText为空

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  private password: string = ''

  build() {
    RelativeContainer() {
      TextInput({text: this.password})
        .onChange((text: string, previewText: PreviewText, options: TextChangeOptions) => {
          this.password = text
        })
    }
    .height('100%')
    .width('100%')
  }
}

如上示例 测试断点发现输入后onChange事件中的previewText中value=’’,offset=-1 请问这是什么情况呢 我在我的其他地方使用也是这样

其次,我想实现一个对用户输入的字符做全角转半角的转换 请问使用哪个api,哪种实现方式好,目前想到的是用onChange事件中获取最新输入的字符,然后对其做字符转换,再拼接到上一次的text中 请问有其他更合适的方法吗


更多关于HarmonyOS鸿蒙Next中textInput的previewText为空的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

1、password添加@State进行状态装饰且使用数据双向绑定

  • 在状态管理V1中,推荐使用$$实现系统组件的双向绑定。
  • @Entry
    @Component
    struct Index {
      [@State](/user/State) message: string = 'Hello World';
      [@State](/user/State) password: string = ''
    
      build() {
        RelativeContainer() {
          //修改的输入文本会自动同步到password中,无需在onChange中二次赋值
          TextInput({text: $$this.password})
            .onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => {
              // 调用全角转半角的函数进行处理
            })
        }
        .height('100%')
        .width('100%')
      }
    }
    
    【!!语法:双向绑定】【API_onSubmit】

2、全角转半角的转换时机建议在文本提交的时候进行转换;

  • 全角转半角可以用正则匹配:
  • /**
     * 全角字符转半角字符(支持字母、数字、符号、空格)
     * @param {string} str - 包含全角字符的输入字符串
     * @returns {string} 转换后的半角字符串
     */
    function fullWidthToHalfWidth(str) {
      if (typeof str !== 'string') return str; // 非字符串直接返回原值
    
      // 正则匹配:全角空格(\u3000) 或 其他全角字符(\uFF01-\uFF5E)
      return str.replace(/[\u3000\uFF01-\uFF5E]/g, (char) => {
        // 全角空格单独处理
        if (char === '\u3000') {
          return ' ';
        }
        // 其他全角字符:Unicode 减去 0xFEE0 得到半角
        return String.fromCharCode(char.charCodeAt(0) - 0xFEE0);
      });
    }
    

更多关于HarmonyOS鸿蒙Next中textInput的previewText为空的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


onSubmit不是回车的事件回调吗 不是应该在每次输入的时候修改输入的字符吗,

对的,您可以在其它提交事件中也做跟onSubmit同样的逻辑处理,上面onSubmit只是为了举例;可以在每次输入的时候修改输入的字符,但是不建议这么做,最好还是在提交时的回调事件中进行处理。

在HarmonyOS Next中,TextInput组件的previewText属性为空时,表示该输入框在未输入状态下不会显示任何预览占位文本。这是该属性的正常行为,其设计目的是为了在用户未输入时保持界面简洁。

在HarmonyOS Next中,TextInputonChange回调里previewText为空(value='', offset=-1)是正常行为。previewText主要用于展示输入法候选词或预输入文本,在用户直接输入最终字符(如字母、数字)时,它通常为空。你观察到的现象表明当前输入操作没有产生预输入文本。

关于全角转半角的需求,你的思路是正确的。推荐在onChange回调中处理,这是最直接的方式。以下是优化后的实现示例:

import { TextInput, PreviewText, TextChangeOptions } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State text: string = '';
  
  // 全角转半角函数
  private toHalfWidth(str: string): string {
    return str.replace(/[\uFF01-\uFF5E]/g, (ch) => {
      return String.fromCharCode(ch.charCodeAt(0) - 0xFEE0);
    });
  }

  build() {
    Column() {
      TextInput({ text: this.text })
        .onChange((value: string, previewText: PreviewText, options: TextChangeOptions) => {
          // 获取新输入的字符(如果有)
          let newText = value;
          if (options && options.addedValue) {
            // 对新输入部分进行转换
            newText = this.toHalfWidth(options.addedValue);
            // 组合:原文本中未变化部分 + 转换后的新输入
            this.text = value.substring(0, options.offset) + newText + value.substring(options.offset + options.addedValue.length);
          } else {
            // 没有addedValue时(如删除、粘贴),直接转换整个文本
            this.text = this.toHalfWidth(value);
          }
        })
    }
    .width('100%')
    .height('100%')
  }
}

关键点:

  1. 使用TextChangeOptions中的addedValueoffset来精确识别新输入的字符,避免对整个字符串重复转换。
  2. 这种方法性能较好,只处理变化的文本部分。
  3. 注意处理没有addedValue的情况(如删除、粘贴操作),此时需要转换整个当前文本。

这种实现方式在输入响应性和性能之间取得了较好的平衡。

回到顶部