Разделитель тысяч без десятичного разделителя на флаттере TextFormField
Я использую https://pub.dev/packages/flutter_masked_text, чтобы отформатировать мой контроллер для автоматического добавления разделителя тысяч в поле валюты. Я использую это для достижения этого.
var controller = new MoneyMaskedTextController(decimalSeparator: '.', thousandSeparator: ',');
Мне не нравится, как это работает, потому что он начинается с 0.00
и автоматически начинает добавлять цифры из десятичной части. Если я напечатаю1000
, это должно стать 1,000
не 1,000.00
. Есть ли способ отформатировать поле контроллера, чтобы добавить разделитель тысяч без десятичного разделителя?
3 ответа
У меня та же проблема, я нашел пользовательский код форматирования ввода раньше как временное решение, которое делает то же самое, затем я изменил его для этого конкретного опыта. Вы можете попробовать это, если это поможет, и не стесняйтесь оптимизировать его.
class DecimalFormatter extends TextInputFormatter {
final int decimalDigits;
DecimalFormatter({this.decimalDigits = 2}) : assert(decimalDigits >= 0);
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue,
TextEditingValue newValue,) {
String newText;
if (decimalDigits == 0) {
newText = newValue.text.replaceAll(RegExp('[^0-9]'), '');
}
else {
newText = newValue.text.replaceAll(RegExp('[^0-9\.]'), '');
}
if(newText.contains('.')) {
//in case if user's first input is "."
if (newText.trim() == '.') {
return newValue.copyWith(
text: '0.',
selection: TextSelection.collapsed(offset: 2),
);
}
//in case if user tries to input multiple "."s or tries to input
//more than the decimal place
else if (
(newText.split(".").length > 2)
|| (newText.split(".")[1].length > this.decimalDigits)
) {
return oldValue;
}
else return newValue;
}
//in case if input is empty or zero
if (newText.trim() == '' || newText.trim() == '0') {
return newValue.copyWith(text: '');
}
else if (int.parse(newText) < 1) {
return newValue.copyWith(text: '');
}
double newDouble = double.parse(newText);
var selectionIndexFromTheRight =
newValue.text.length - newValue.selection.end;
String newString = NumberFormat("#,##0.##").format(newDouble);
return TextEditingValue(
text: newString,
selection: TextSelection.collapsed(
offset: newString.length - selectionIndexFromTheRight,
),
);
}
}
Я использовал специальный форматер ввода текста, чтобы сделать что-то вроде этого:
class CustomTextInputFormatter extends TextInputFormatter {
@override
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.extentOffset;
List<String> chars = newValue.text.replaceAll(' ', '').split('');
String newString = '';
for (int i = 0; i < chars.length; i++) {
if (i % 3 == 0 && i != 0) newString += ' ';
newString += chars[i];
}
return TextEditingValue(
text: newString,
selection: TextSelection.collapsed(
offset: newString.length - selectionIndexFromTheRight,
),
);
} else {
return newValue;
}
}
}
Затем в вашем TextField:
TextField(
controller: _textController,
keyboardType: TextInputType.number,
inputFormatters: [CustomTextInputFormatter()],
)
Я никогда не пробовал этот пакет, но вижу, что MoneyMaskedTextController()
имеет precision
параметр.
попробуйте что-нибудь вроде этого:
var controller = new MoneyMaskedTextController(precision: 0, decimalSeparator: '.', thousandSeparator: ',');