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;
}
}
}