HarmonyOS鸿蒙Next中TextInput inputFilter如何限制输入数字范围-50~150?

HarmonyOS鸿蒙Next中TextInput inputFilter如何限制输入数字范围-50~150? 使用正则表达式^-?([1-9]?[0-9][1-9]|150)$,实际无法支持负数,无法限制数字输入范围。

4 回复

您好,TextInput组件的inputFilter仅支持单个字符匹配,不支持字符串匹配。可通过onChangeonWillChange等事件处理文本内容。

【背景知识】
input是单行文本输入框组件,常用于响应用户的输入操作,比如手机号输入,表单的输入等。针对输入的内容格式以及长度用户往往希望进行限制,常见的场景如下:

  1. 限制输入的格式:

    • 限制只能输入手机号或者邮箱;
    • 首位不允许出现空格;
    • 限制输入中文、英文、数字或者emoji表情包;
    • 限制输入两位小数。
  2. 限制输入的长度:

    • 限制文本的内容长度,比如不超过20个字符;
    • 限制文本的字节数量,比如不超过32个字节。

【解决方案】

  1. 限制输入的格式:

    • 限制只能输入手机号或者邮箱; input的type属性支持设置不同的输入框类型,利用InputType.PhoneNumber即可限制类型为手机号码:

      build() {
        Column() {
          TextInput({ placeholder: '请输入手机号码' })
            .width('70%')
            .height('58')
            .type(InputType.PhoneNumber)
            .maxLength(11)
        }
        .height('100%')
        .width('100%')
      }
      
    • 首位不允许出现空格; 利用onWillInsert事件监听将要输入的字符,如果字符以空格开头则阻止输入:

      @Component
      @Entry
      export struct Index {
        @State text: string = ''
        controller: TextInputController = new TextInputController()
        @State insertValue: string = "";
      
        build() {
          Column() {
            TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
              .width('70%')
              .height('58')
              .onWillInsert((info: InsertValue) => {
                // 在将要输入时调用的回调。在返回true时,表示正常插入,返回false时,表示不插入。
                this.insertValue = info.insertValue;
                if (this.insertValue.startsWith(' ')) {
                  return false
                } else {
                  return true
                }
              })
          }
          .height('100%')
          .width('100%')
        }
      }
      
    • 限制输入中文、英文、数字或者emoji表情包; input的inputFilter属性支持输入正则表达式,以下使用正则表达式限制中文字符输入:

      build() {
        Column() {
          TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
            .width('70%')
            .height('58')
            .inputFilter('[^\u4e00-\u9fa5]', (val) => {
              console.error('限制输入中文内容 : ' + val);
              return 0;
            })
        }
        .height('100%')
        .width('100%')
      }
      
    • 限制输入两位小数。 利用inputFilter限制输入格式,并在onChange方法内使用parseFloat和toFixed方法组合使用保留两位小数:

      @Component
      @Entry
      export struct Index {
        @State text: string = ''
        @State insertValue: string = "";
        controller: TextInputController = new TextInputController()
      
        build() {
          Column() {
            Text(`输入的值: ${this.insertValue}`)
            TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
              .width('70%')
              .height('58')
              .type(InputType.NUMBER_DECIMAL)
              .onChange((value) => {
                let number = parseFloat(value);
                // 使用toFixed方法将浮点数格式化为保留两位小数的字符串
                this.insertValue = number.toFixed(2);
                console.log('获取到的值' + this.insertValue)
              })
              .inputFilter('^-?\\d*\\.?\\d{0,2}$', (val) => {
                console.log('限制输入两位小数 : ' + val)
              })
          }
          .height('100%')
          .width('100%')
        }
      }
      
  2. 限制输入的长度:

    • 限制文本的内容长度,比如不超过20个字符; input的maxLength属性可以限制文本的最大输入字符数:

      build() {
        Column() {
          TextInput()
            .width('70%')
            .height('58')
            .maxLength(10)
        }
        .height('100%')
        .width('100%')
      }
      
    • 限制文本的字节数量,比如不超过32个字节。 input的onChange事件在输入内容发生变化时触发,获取到输入的字符串后循环遍历内容,利用charCodeAt方法获取该字符的UniCode码,若UniCode码 > 255则为中文,可以判断为2个字符。代码实现如下:

      @Component
      @Entry
      export struct Index {
        @State text: string = ''
        @State lastText: string = "";
        controller: TextInputController = new TextInputController()
      
        getByteLength(str: string) {
          let byteLength = 0;
          for (let i = 0; i < str.length; i++) {
            const charCode = str.charCodeAt(i);
            if (charCode <= 0xff) {
              byteLength += 1;
            } else {
              byteLength += 2;
            }
          }
          return byteLength;
        }
      
        build() {
          Column() {
            TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
              .width('70%')
              .height('58')
              .onChange((value: string) => {
                let num = this.getByteLength(value)
                console.log('num -', num);
                if (num > 32) {
                  this.text = ' '
                  this.text = this.lastText
                } else {
                  this.lastText = value
                  this.text = value
                }
              })
          }
          .height('100%')
          .width('100%')
        }
      }
      

【常见FAQ】

Q:常见的用正则表达式过滤的场景有哪些? A:较为常见的有英文和数字的过滤、中文的过滤以及手机号、邮箱、身份证号、银行卡号等表单验证场景。

Q:以上方法在其他组件适用吗? A:TextInput、TextArea都是输入框组件,以上方法在TextArea上也适用。

【总结】
TextInput限制输入主要在内容格式以及长度方面。设置typeinputFilter以及maxLength属性即可快速达到所需限制效果,如果需要自定义实现限制策略,则可以使用onWillInsertonChange事件获取到用户输入的内容,然后针对字符串进行限制处理。

更多关于HarmonyOS鸿蒙Next中TextInput inputFilter如何限制输入数字范围-50~150?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


正则表达式不对,可以参考如下demo

TextInput({ text: this.text, placeholder: 'input your word...', controller: this.controller })
  .type(InputType.Number)
  .inputFilter('^(-(0|[1-4]\\d|50)|0|([1-9]\\d?|1[0-4]\\d|150))$', (e) => {
    console.log(JSON.stringify(e));
  })

在HarmonyOS鸿蒙Next中,可以通过TextInput组件的inputFilter属性来限制输入的数字范围。使用正则表达式可以轻松实现这一功能。例如,你可以设置inputFilter的正则表达式为"^-?[0-9]{1,3}$",并结合自定义的校验逻辑,确保输入的数字在-50到150之间。

在HarmonyOS Next中,可以使用TextInput的inputFilter属性结合自定义逻辑来限制输入范围为-50~150。以下是实现方案:

  1. 使用正则表达式结合自定义验证:
TextInput()
  .inputFilter((value: string) => {
    // 允许空值(用于删除操作)
    if (value === '') return true;
    
    // 验证数字格式和范围
    const num = Number(value);
    if (isNaN(num)) return false;
    
    return num >= -50 && num <= 150;
  })
  1. 或者使用正则表达式优化版本:
TextInput()
  .inputFilter((value: string) => {
    return /^(-?([0-4]?[0-9]|50)|-50|([0-9]?[0-9]|1[0-4][0-9]|150))$/.test(value) || value === '';
  })

注意事项:

  • 第一种方案更直观,直接进行数值范围判断
  • 第二种正则表达式能精确匹配-50到150的范围
  • 两种方案都考虑了空字符串情况,允许用户删除内容
  • 建议配合onChange事件做最终验证,因为inputFilter在部分输入中间状态可能无法完全拦截

这个实现能正确处理负数输入,并确保最终输入值在-50到150范围内。

回到顶部