Разделитель тысяч без десятичного разделителя на флаттере 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: ',');
Другие вопросы по тегам