Flutter:在TextInputFormatter中使用NumberFormat

时间:2018-08-08 05:03:01

标签: dart flutter

我正在尝试在NumberFromatter中使用TextInputFormatter,但是当我尝试使用它时,它完全搞砸了!这是我的TextInputFormatter实现代码:

class NumericTextFormatter extends TextInputFormatter {
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    if(newValue.text.length > 0) {
      int num = int.parse(newValue.text.replaceAll(',', ''));
      final f = new NumberFormat("#,###");
      return newValue.copyWith(text: f.format(num));
    } else { 
      return newValue.copyWith(text: '');
    }
  }
}

因此,当我将此格式化程序添加到TextField并尝试键入1到9时,我希望看到的内容类似于:123,456,789

但这是TextField中显示的内容:

1
12
123
1,234
12,354 <- this is where it starts
123,564
1,235,674
12,356,874 <- and it happends again

似乎光标在添加一个字符后移动。那么有人可以帮我吗?

2 个答案:

答案 0 :(得分:4)

这是因为在格式化值之后,您要添加一个新字符,但文本选择保持在同一位置,少一个字符,这会导致预期的行为

您可以这样修改TextInputFormatter

固定为支持所有语言环境并记住光标位置

class NumericTextFormatter extends TextInputFormatter {
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue, TextEditingValue newValue) {
    if (newValue.text.length == 0) {
      return newValue.copyWith(text: '');
    } else if (newValue.text.compareTo(oldValue.text) != 0) {
      int selectionIndexFromTheRight = newValue.text.length - newValue.selection.end;
      final f = new NumberFormat("#,###");
      int num = int.parse(newValue.text.replaceAll(f.symbols.GROUP_SEP, ''));
      final newString = f.format(num);
      return new TextEditingValue(
        text: newString,
        selection: TextSelection.collapsed(offset: newString.length - selectionIndexFromTheRight),
      );
    } else {
      return newValue;
    }
  }
}

答案 1 :(得分:1)

根据答案并针对欧洲人寻求快速解决方案

class NumericTextFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final currencySymbol = '€';
    if (newValue.text.isEmpty || newValue.text.trim() == currencySymbol) {
      return newValue.copyWith(text: '');
    } else if (newValue.text.compareTo(oldValue.text) != 0) {
      var selectionIndexFromTheRight =
          newValue.text.length - newValue.selection.end;
      final f =
          NumberFormat.currency(locale: 'de', decimalDigits: 0, symbol: '');
      var num = int.parse(newValue.text.replaceAll(RegExp('[^0-9]'), ''));
      final newString = '$currencySymbol ' + f.format(num).trim();
      return TextEditingValue(
        text: newString,
        selection: TextSelection.collapsed(
            offset: newString.length - selectionIndexFromTheRight),
      );
    } else {
      return newValue;
    }
  }
}