Allow only two decimal number in flutter input?

后端 未结 9 1237
误落风尘
误落风尘 2020-12-30 07:03

I want only two digits after decimal point in the flutter input.User can\'t add more than two digits after decimal point.

相关标签:
9条回答
  • 2020-12-30 07:12

    I extended the functionalities ... I hope you can find it useful. Tell me if you can improve even more please.

    import 'package:flutter/services.dart';
    import 'dart:math' as math;
    
    class DecimalTextInputFormatter extends TextInputFormatter {
      DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues})
          : assert(decimalRange == null || decimalRange >= 0,
                'DecimalTextInputFormatter declaretion error');
    
      final int decimalRange;
      final bool activatedNegativeValues;
    
      @override
      TextEditingValue formatEditUpdate(
        TextEditingValue oldValue, // unused.
        TextEditingValue newValue,
      ) {
        TextSelection newSelection = newValue.selection;
        String truncated = newValue.text;
    
    
    if (newValue.text.contains(' ')) {
      return oldValue;
    }
    
    if (newValue.text.isEmpty) {
      return newValue;
    } else if (double.tryParse(newValue.text) == null &&
        !(newValue.text.length == 1 &&
            (activatedNegativeValues == true ||
                activatedNegativeValues == null) &&
            newValue.text == '-')) {
      return oldValue;
    }
    
    if (activatedNegativeValues == false &&
        double.tryParse(newValue.text) < 0) {
      return oldValue;
    }
    
    if (decimalRange != null) {
      String value = newValue.text;
    
      if (decimalRange == 0 && value.contains(".")) {
        truncated = oldValue.text;
        newSelection = oldValue.selection;
      }
    
      if (value.contains(".") &&
          value.substring(value.indexOf(".") + 1).length > decimalRange) {
        truncated = oldValue.text;
        newSelection = oldValue.selection;
      } else if (value == ".") {
        truncated = "0.";
    
        newSelection = newValue.selection.copyWith(
          baseOffset: math.min(truncated.length, truncated.length + 1),
          extentOffset: math.min(truncated.length, truncated.length + 1),
        );
      }
    
      return TextEditingValue(
        text: truncated,
        selection: newSelection,
        composing: TextRange.empty,
      );
    }
    return newValue;
    }
    }
    
    0 讨论(0)
  • 2020-12-30 07:13

    Maybe a little late for you, but I also improved a little:

    1. Allow only 1 .
    2. Allow negative
    3. Place negative sign on beginning

    Hope it helps ;)

    import 'package:flutter/services.dart';
    
    class NumberTextInputFormatter extends TextInputFormatter {
      NumberTextInputFormatter({this.decimalRange}) : assert(decimalRange == null || decimalRange > 0);
    
      final int decimalRange;
    
      @override
      TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
        TextEditingValue _newValue = this.sanitize(newValue);
        String text = _newValue.text;
    
        if (decimalRange == null) {
          return _newValue;
        }
    
        if (text == '.') {
          return TextEditingValue(
            text: '0.',
            selection: _newValue.selection.copyWith(baseOffset: 2, extentOffset: 2),
            composing: TextRange.empty,
          );
        }
    
        return this.isValid(text) ? _newValue : oldValue;
      }
    
      bool isValid(String text) {
        int dots = '.'.allMatches(text).length;
    
        if (dots == 0) {
          return true;
        }
    
        if (dots > 1) {
          return false;
        }
    
        return text.substring(text.indexOf('.') + 1).length <= decimalRange;
      }
    
      TextEditingValue sanitize(TextEditingValue value) {
        if (false == value.text.contains('-')) {
          return value;
        }
    
        String text = '-' + value.text.replaceAll('-', '');
    
        return TextEditingValue(text: text, selection: value.selection, composing: TextRange.empty);
      }
    }
    

    and (don't forget to import the previous class)

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class NumberFormField extends StatelessWidget {
      final InputDecoration decoration;
      final TextEditingController controller;
      final int decimalRange;
    
      const NumberFormField({Key key, this.decoration, this.controller, this.decimalRange}) :super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return TextFormField(
          decoration: this.decoration,
          controller: this.controller,
          keyboardType: TextInputType.numberWithOptions(decimal: true),
          inputFormatters: [
            WhitelistingTextInputFormatter(RegExp(r'[\d+\-\.]')),
            NumberTextInputFormatter(decimalRange: this.decimalRange),
          ],
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-30 07:17

    after Flutter Version v1.20.0-1.0. use

    TextFormField(
      keyboardType: TextInputType.numberWithOptions(decimal: true),
      inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
      ],
    ),
    
    0 讨论(0)
  • 2020-12-30 07:17

    The answer by @AjayKumar allows to limit text input to required decimal places.But my requirement was to avoid another character from keyboard except the number and a dot.So, I updated @AjayKumar's above answer

    import 'package:flutter/services.dart';
    import 'dart:math' as math;   
    
    class DecimalTextInputFormatter extends TextInputFormatter {
    DecimalTextInputFormatter({this.decimalRange})
      : assert(decimalRange == null || decimalRange > 0);
    
    final int decimalRange;
    
    @override
    TextEditingValue formatEditUpdate(
    TextEditingValue oldValue, // unused.
    TextEditingValue newValue,
    ) {
    TextSelection newSelection = newValue.selection;
    String truncated = newValue.text;
    
    if (decimalRange != null) {
      String value = newValue.text;
    
      if (value.contains(',') ||
          value.contains('-') ||
          value.contains(' ') ||
          value.contains('..')) {
        truncated = oldValue.text;
        newSelection = oldValue.selection;
      } else if (value.contains(".") &&
          value.substring(value.indexOf(".") + 1).length > decimalRange) {
        truncated = oldValue.text;
        newSelection = oldValue.selection;
      } else if (value == ".") {
        truncated = "0.";
    
        newSelection = newValue.selection.copyWith(
          baseOffset: math.min(truncated.length, truncated.length + 1),
          extentOffset: math.min(truncated.length, truncated.length + 1),
        );
      }
    
      return TextEditingValue(
        text: truncated,
        selection: newSelection,
        composing: TextRange.empty,
      );
    }
    return newValue;
    

    } }

    0 讨论(0)
  • 2020-12-30 07:21

    And avoiding non necessary zeros... Please debug this code.

    import 'dart:math' as math;
    
    import 'package:flutter/services.dart';
    
    class DecimalTextInputFormatter extends TextInputFormatter {
      DecimalTextInputFormatter({this.decimalRange, this.activatedNegativeValues})
          : assert(decimalRange == null || decimalRange >= 0,
                'DecimalTextInputFormatter declaretion error');
    
      final int decimalRange;
      final bool activatedNegativeValues;
    
      @override
      TextEditingValue formatEditUpdate(
        TextEditingValue oldValue, // unused.
        TextEditingValue newValue,
      ) {
        TextSelection newSelection = newValue.selection;
        String truncated = newValue.text;
    
        if (newValue.text.contains(' ')) {
          return oldValue;
        }
    
        if (newValue.text.isEmpty) {
          return newValue;
        } else if (double.tryParse(newValue.text) == null &&
            !(newValue.text.length == 1 &&
                (activatedNegativeValues == true ||
                    activatedNegativeValues == null) &&
                newValue.text == '-')) {
          return oldValue;
        }
    
        if (activatedNegativeValues == false &&
            double.tryParse(newValue.text) < 0) {
          return oldValue;
        }
    
        if ((double.tryParse(oldValue.text) == 0 && !newValue.text.contains('.'))) {
          if (newValue.text.length >= oldValue.text.length) {
            return oldValue;
          }
        }
    
        if (decimalRange != null) {
          String value = newValue.text;
    
          if (decimalRange == 0 && value.contains(".")) {
            truncated = oldValue.text;
            newSelection = oldValue.selection;
          }
    
          if (value.contains(".") &&
              value.substring(value.indexOf(".") + 1).length > decimalRange) {
            truncated = oldValue.text;
            newSelection = oldValue.selection;
          } else if (value == ".") {
            truncated = "0.";
    
            newSelection = newValue.selection.copyWith(
              baseOffset: math.min(truncated.length, truncated.length + 1),
              extentOffset: math.min(truncated.length, truncated.length + 1),
            );
          }
    
          return TextEditingValue(
            text: truncated,
            selection: newSelection,
            composing: TextRange.empty,
          );
        }
        return newValue;
      }
    }
    
    0 讨论(0)
  • 2020-12-30 07:29

    A shorter Version of DecimalTextInputFormatter using Regexp:

    class DecimalTextInputFormatter extends TextInputFormatter {
    
      DecimalTextInputFormatter({int decimalRange, bool activatedNegativeValues})
      : assert(decimalRange == null || decimalRange >= 0,
        'DecimalTextInputFormatter declaretion error') {
        String dp = (decimalRange != null && decimalRange > 0) ? "([.][0-9]{0,$decimalRange}){0,1}" : "";
        String num = "[0-9]*$dp";
    
        if(activatedNegativeValues) {
          _exp = new RegExp("^((((-){0,1})|((-){0,1}[0-9]$num))){0,1}\$");
        }
        else {
          _exp = new RegExp("^($num){0,1}\$");
        }
      }
    
      RegExp _exp;
    
      @override
      TextEditingValue formatEditUpdate(
        TextEditingValue oldValue,
        TextEditingValue newValue,
      ) {
        if(_exp.hasMatch(newValue.text)){
          return newValue;
        }
        return oldValue;
      }
    }
    
    0 讨论(0)
提交回复
热议问题