Flutter: Using NumberFormat in TextInputFormatter
This is because after you format the value you are adding a new char but the text selection remains at the same position, one char less, this cause an expected behavior
You can modify your TextInputFormatter
like this:
Fixed to support all locales and to remember cursor position
class NumericTextFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue) { if (newValue.text.isEmpty) { return newValue.copyWith(text: ''); } else if (newValue.text.compareTo(oldValue.text) != 0) { final int selectionIndexFromTheRight = newValue.text.length - newValue.selection.end; final f = NumberFormat("#,###"); final number = int.parse(newValue.text.replaceAll(f.symbols.GROUP_SEP, '')); final newString = f.format(number); return TextEditingValue( text: newString, selection: TextSelection.collapsed( offset: newString.length - selectionIndexFromTheRight), ); } else { return newValue; } }}
Based on the answer and for people from Europe looking for a quick fix
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; } }}