You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中TextFormField输入两次-或空格内容消失问题求助

问题原因及解决方法

原因

你给FilteringTextInputFormatter.allow的正则加了^和$锚定符,这会让Formatter每次都检查完整输入文本是否符合规则。虽然连续的“-”或空格本身匹配^[0-9\s-]+$,但在输入过程中(比如快速连续输入、光标不在末尾的编辑操作),可能出现临时文本状态不满足正则的情况,触发Formatter直接清空文本。

另外,正则里的+要求至少有一个字符,当文本被清空到空字符串时,也会因为不匹配规则出现异常,但这不是你当前的核心问题。

解决方法

去掉正则中的^和$锚定符,让Formatter只检查单个输入字符是否允许,而非整个文本:

TextFormField(
  maxLength: 12,
  buildCounter: (
    BuildContext context, {
    required int currentLength,
    required bool isFocused,
    required int? maxLength,
  }) {
    return null;
  },
  cursorColor: Colors.black,
  decoration: InputDecoration(
    labelText: 'Just Put numbers',
    labelStyle: TextStyle(color: Colors.black),
    focusedBorder: OutlineInputBorder(
      borderSide: BorderSide(
        color: Colors.black,
      ),
    ),
  ),
  inputFormatters: [
    // 去掉^和$,仅匹配单个允许的字符
    FilteringTextInputFormatter.allow(RegExp(r'[0-9\s-]')),
  ],
)

进阶优化(适配xxx-xxxx-xxxx格式)

如果想严格限制输入为类似xxx-xxxx-xxxx的格式(禁止连续分隔符、自动补充分隔符),可以自定义TextInputFormatter,示例如下:

class NumberWithSeparatorFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    // 过滤掉非数字、空格、横杠的字符
    String cleaned = newValue.text.replaceAll(RegExp(r'[^0-9\s-]'), '');
    
    // 把连续的分隔符统一替换成单个横杠
    cleaned = cleaned.replaceAll(RegExp(r'[\s-]+'), '-');
    
    // 按xxx-xxxx-xxxx的格式拆分重组
    List<String> parts = [];
    String temp = cleaned.replaceAll('-', '');
    if (temp.length >= 3) {
      parts.add(temp.substring(0, 3));
      temp = temp.substring(3);
    }
    if (temp.length >= 4) {
      parts.add(temp.substring(0, 4));
      temp = temp.substring(4);
    }
    if (temp.isNotEmpty) {
      parts.add(temp);
    }
    String formatted = parts.join('-');
    
    // 修正光标位置,避免格式调整后光标错位
    int cursorPosition = newValue.selection.end;
    int delta = formatted.length - cleaned.length;
    cursorPosition += delta;
    cursorPosition = cursorPosition.clamp(0, formatted.length);
    
    return TextEditingValue(
      text: formatted,
      selection: TextSelection.collapsed(offset: cursorPosition),
    );
  }
}

使用时替换inputFormatters:

inputFormatters: [
  NumberWithSeparatorFormatter(),
],

内容的提问来源于stack exchange,提问作者DLKIM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:16:14