Backspace 不能与 TextInputFormatter 一起正常工作

int*_*tor 8 dart flutter

我正在尝试创建自定义 InputTextFormatter。格式化程序用空格分隔数千个并将点后的字符数限制为 2 个字符。

我想将光标移动到 TextField 值的末尾,但根据我在达到限制(2 个字符)后尝试输入附加字符的次数,实际光标看起来会进一步移动。看起来选择不适用于生成的 TextEditingValue。

重现步骤:

  1. 在 TextField 中输入“12.34”。
  2. 例如,保持以前的值尝试添加“111”。
  3. 按退格键。没发生什么事。

预期行为:按一次退格键必须删除 TextField 中的最后一个字符。

class MoneyFormatter extends TextInputFormatter {
  MoneyFormatter({this.maxLength = 30, this.decimals = 0});
  final int maxLength;
  final int decimals;

  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    print('---------- newValue.selection.extentOffset : ${newValue.selection.extentOffset}');
    String output = newValue.text.formatAsCurrency(decimals: decimals);
    var result = TextEditingValue(
      text: output,
      //this line doesn't have any effect
      selection: TextSelection.collapsed(offset: output.length),
    );
    print('---------- result.selection.extentOffset : ${result.selection.extentOffset}');
    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)

每增加一个字符都result.selection.extentOffset保持不变,但尽管返回了,但newValue.selection.extentOffset增加了1selection: TextSelection.collapsed(offset: output.length)

extension FormatAsCurrency on String {
  String formatAsCurrency({int decimals = 0, String ifNullReturn}) {
    if (this == null) return ifNullReturn;
    if (this.isEmpty) return '';
    String output = this;
    if (output[0] == '.') output = '0' + output;
    var chunks = this.withoutTrailingDots.split('.');
    output = chunks[0].separatedThousands;
    if (decimals == 0 || chunks.length == 1) return output;
    output += '.' + chunks[1].limitLengthTo(decimals).withoutTrailingZeros;
    return output;
  }
}

Run Code Online (Sandbox Code Playgroud)

我知道TextInputFormatterpub.dev 上还有其他类似flutter_multi_formatter 的s ,我已经尝试了所有这些,问题保持不变。

小智 3

在正则表达式中使用 \b :

TextField(
                            controller: tvMobile,
                            keyboardType: TextInputType.number,
                            inputFormatters: <TextInputFormatter>[
                              FilteringTextInputFormatter.allow(
                                  RegExp(r'[0-9,\b]')), // <-- Use \b in your regex here so backspace works.
                            ],
                            maxLength: 10,
                            style: TextStyle(
                              color: Colors.white,
                              fontFamily: "Roboto",
                              fontWeight: FontWeight.w300,
                            ),
                            decoration: InputDecoration(
                              labelStyle: TextStyle(
                                color: Colors.white,
                                fontFamily: "Roboto",
                                fontWeight: FontWeight.w300,
                              ),
                              fillColor: Colors.white,
                              enabledBorder: UnderlineInputBorder(
                                borderSide:
                                    BorderSide(color: Colors.yellow),
                              ),
                              focusedBorder: UnderlineInputBorder(
                                borderSide:
                                    BorderSide(color: Colors.yellow),
                              ),
                              hintText: 'Mobile Number',
                              hintStyle: TextStyle(
                                color: Colors.grey,
                                fontFamily: "Roboto",
                                fontWeight: FontWeight.w300,
                              ),
                            ),
                          ),
Run Code Online (Sandbox Code Playgroud)