Тысячный разделитель во флейте
Есть ли способ сделать разделитель тысяч при вводе чисел в TextFormField
в трепете? Это мойTextFormField
child: TextFormField(
decoration: InputDecoration(
border: const OutlineInputBorder()),
keyboardType: TextInputType.number,
),
3 ответа
Решение
Во Flutter нет ничего, что могло бы справиться с этим. Вам придется использовать свой собственный настраиваемый форматировщик текста. (Получено из этого ответа.)
import 'package:flutter/services.dart';
class ThousandsSeparatorInputFormatter extends TextInputFormatter {
static const separator = ','; // Change this to '.' for other locales
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
// Short-circuit if the new value is empty
if (newValue.text.length == 0) {
return newValue.copyWith(text: '');
}
// Handle "deletion" of separator character
String oldValueText = oldValue.text.replaceAll(separator, '');
String newValueText = newValue.text.replaceAll(separator, '');
if (oldValue.text.endsWith(separator) &&
oldValue.text.length == newValue.text.length + 1) {
newValueText = newValueText.substring(0, newValueText.length - 1);
}
// Only process if the old value and new value are different
if (oldValueText != newValueText) {
int selectionIndex =
newValue.text.length - newValue.selection.extentOffset;
final chars = newValueText.split('');
String newString = '';
for (int i = chars.length - 1; i >= 0; i--) {
if ((chars.length - 1 - i) % 3 == 0 && i != chars.length - 1)
newString = separator + newString;
newString = chars[i] + newString;
}
return TextEditingValue(
text: newString.toString(),
selection: TextSelection.collapsed(
offset: newString.length - selectionIndex,
),
);
}
// If the new value and old value are the same, just return as-is
return newValue;
}
}
Применение:
TextField(
decoration: InputDecoration(
border: const OutlineInputBorder(),
),
keyboardType: TextInputType.number,
inputFormatters: [ThousandsSeparatorInputFormatter()],
),
Ответ от @Abion47 работает хорошо, за исключением случаев, когда ваше значение содержит десятичные знаки. Эта адаптация также обрабатывает десятичные числа.
class ThousandsSeparatorInputFormatter extends TextInputFormatter {
static const separator = ','; // Change this to '.' for other locales
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
// Short-circuit if the new value is empty
if (newValue.text.length == 0) {
return newValue.copyWith(text: '');
}
// Handle "deletion" of separator character
String oldValueText = oldValue.text.replaceAll(separator, '');
String newValueText = newValue.text.replaceAll(separator, '');
if (oldValue.text.endsWith(separator) &&
oldValue.text.length == newValue.text.length + 1) {
newValueText = newValueText.substring(0, newValueText.length - 1);
}
// Only process if the old value and new value are different
if (oldValueText != newValueText) {
// Split the string into its integer and decimal parts
List<String> parts = newValueText.split('.');
int selectionIndex =
newValue.text.length - newValue.selection.extentOffset;// + (parts.length > 1 ? parts[1].length : 0);
final chars = parts[0].split('');
String newString = '';
for (int i = chars.length - 1; i >= 0; i--) {
if ((chars.length - 1 - i) % 3 == 0 && i != chars.length - 1)
newString = separator + newString;
newString = chars[i] + newString;
}
return TextEditingValue(
text: newString.toString() + (parts.length > 1 ? '.' + parts[1] : ''),
selection: TextSelection.collapsed(
offset: newString.length - selectionIndex + (parts.length > 1 ? parts[1].length + 1 : 0),
),
);
}
// If the new value and old value are the same, just return as-is
return newValue;
}
}
Сначала добавьте пакет intl flutter
dependencies:
intl: ^0.16.1
Теперь используйте NumberFormat
var formatter = new NumberFormat("#,###");
print(formatter.format(1234)), // this will be: 1,234