项目中存在一个输入框,只能提交中文字符串,于是使用了如下的方法实现

TextField(
  /// 输入文本格式过滤
  inputFormatters: [
    /// 输入的内容长度为 10 位
    LengthLimitingTextInputFormatter(10),

    /// 只能输入汉字或者字母或数字
    WhitelistingTextInputFormatter(
      RegExp("[a-zA-Z]|[\u4e00-\u9fa5]|[0-9]"),
    ),
    ],
  ),

但是上线运行之后,发现在iOS原生拼音输入法中,只能一个字一个字输入,每次输入超过一个字就会直接变成拼音字母,并且长度限制在遇到中文拼音输入法后也会失效

有问题的输入框

于是通过自定义过滤器的方法,解决了这个问题

  TextField(
    inputFormatters: [
    /// 输入的内容长度为 10 位
    CustomizedLengthTextInputFormatter(10),

    /// 只能输入汉字或者字母或数字
    CustomizedTextInputFormatter(
      filterPattern: RegExp("[a-zA-Z]|[\u4e00-\u9fa5]|[0-9]"),
    ),
   ],
  ),

修复后的输入框

/// 自定义兼容中文拼音输入法正则校验输入框
class CustomizedTextInputFormatter extends TextInputFormatter {
  final Pattern filterPattern;

  CustomizedTextInputFormatter({this.filterPattern})
      : assert(filterPattern != null);

  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {
    if (newValue.isComposingRangeValid) return newValue;
    return FilteringTextInputFormatter.allow(filterPattern)
        .formatEditUpdate(oldValue, newValue);
  }
}

/// 自定义兼容中文拼音输入法长度限制输入框
class CustomizedLengthTextInputFormatter extends TextInputFormatter {
  final int maxLength;

  CustomizedLengthTextInputFormatter(this.maxLength);

  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {
    if (newValue.isComposingRangeValid) return newValue;
    return LengthLimitingTextInputFormatter(maxLength)
        .formatEditUpdate(oldValue, newValue);
  }
}

关键方法在于判断当前输入框是否存在未完成的字符串,如果存在,则不做限制,否则根据参数进行限制

/// Whether the [composing] range is a valid range within [text].
  ///
  /// Returns true if and only if the [composing] range is normalized, its start
  /// is greater than or equal to 0, and its end is less than or equal to
  /// [text]'s length.
  ///
  /// If this property is false while the [composing] range's `isValid` is true,
  /// it usually indicates the current [composing] range is invalid because of a
  /// programming error.
  bool get isComposingRangeValid => composing.isValid && composing.isNormalized && composing.end <= text.length;

但是属性 composing 听说还存在bug,使用的时候要注意,很有可能还有坑等着

参考:
https://blog.csdn.net/NNadn/article/details/90673361
https://blog.csdn.net/qq_27494201/article/details/106638855

解决方案:
https://juejin.im/post/6886279718543294478
https://github.com/flutter/flutter/pull/69553

顿悟:
https://github.com/AlexV525

内容转载自文章

作者:各种垫底
链接:https://www.jianshu.com/p/d2c50b9271d3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最后修改:2022 年 01 月 27 日
如果觉得我的文章对你有用,请随意赞赏或留下你的评论~