【问题标题】:Allow only two decimal number in flutter input?颤振输入中只允许两个十进制数?
【发布时间】:2023-03-21 21:25:01
【问题描述】:

我只想要颤振输入中的小数点后两位数。用户不能在小数点后添加超过两位数。

【问题讨论】:

  • 您可以使用TextEditingController 来监听输入并在那里管理您的逻辑。
  • 所以没有输入格式化程序的可能性。例如.inputFormatters: (keyboardType == TextInputType.number) ? [WhitelistingTextInputFormatter.digitsOnly] : [],
  • 据我所知,他们不会帮助你,他们只能让你选择特定类型的键盘。
  • 非常感谢,不知道为什么这个问题得-2分。
  • 可能是因为你没有展示任何你尝试过的代码,而且没有人会从头开始为你编写解决方案。

标签: dart flutter flutter-layout


【解决方案1】:

给你! 希望对你有帮助:)

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'dart:math' as math;

void main() {
  runApp(new MaterialApp(home: new MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter"),
      ),
      body: Form(
        child: ListView(
          children: <Widget>[
            TextFormField(
              inputFormatters: [DecimalTextInputFormatter(decimalRange: 2)],
              keyboardType: TextInputType.numberWithOptions(decimal: true),
            )
          ],
        ),
      ),
    );
  }
}

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

【讨论】:

  • @AjayKumar 代码 'math.min(truncated.length, truncated.length + 1)' 看起来很多余。
  • 这个问题是强制使用 '.'不支持交换句点和逗号的语言环境。
  • @AjayKumar 谢谢,为我工作。在某些键盘上,需要单击该点来添加减号。在这个类中,您可以在输入所有值后输入减号。如果我检查一下,我会添加。再次感谢。
  • 如果用户在小数点后添加更多数字,则在到达前两个数字之前删除无效。
  • 嘿,如果设备使用使用逗号, 作为小数点分隔符的区域设置(如西班牙语),这将不起作用
【解决方案2】:

这是一个适合我的解决方案

TextFormField(
    inputFormatters: [
        WhitelistingTextInputFormatter(RegExp(r'^\d+\.?\d{0,2}')),
    ],
)

如果你想允许像 (.21) 或 (.25) 这样的输入

这是一个解决方案-

TextFormField(
    inputFormatters: [
        WhitelistingTextInputFormatter(RegExp(r'^(\d+)?\.?\d{0,2}')),
    ],
)

【讨论】:

  • 您的解决方案允许用户在整数部分输入额外的点
  • 如何限制小数点前 4 位 @theboringdeveloper
  • 最简单的解决方案,要补充一点,WhitelistingTextInputFormatter 已弃用,请改用FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))
【解决方案3】:

Flutter 版本 v1.20.0-1.0 之后。使用

TextFormField(
  keyboardType: TextInputType.numberWithOptions(decimal: true),
  inputFormatters: [
    FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
  ],
),

【讨论】:

  • 如何限制小数点前0-9之间的4位数字@Nuqo
【解决方案4】:

使用 Regexp 的 DecimalTextInputFormatter 的更短版本:

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

【讨论】:

  • 谢谢,这段代码也忽略了字母和符号,只留下数字和点。
  • 这是允许输入多个 000000000, 0s
【解决方案5】:

对于 Dart 2.00+

TextFormField(
  keyboardType: TextInputType.numberWithOptions(decimal: true),
  inputFormatters: [
    // Allow Decimal Number With Precision of 2 Only
    FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,2}')),
  ],

它允许像1..898.99这样的小数

【讨论】:

  • 某些语言使用逗号代替
【解决方案6】:

Dart SDK 版本:2.13.4(稳定) Flutter 2.2.3 • 通道稳定

我在 2021 年 7 月 25 日写这个答案,建议稍微简单一点的解决方案,只使用内置 TextField 的 inputFormatters

我试图确保你们所有人,该字段不会接受超过 2 的浮点数(接受:12.25 与不接受:65.536)。而且,它不接受多个点,只接受一个点(接受:12.25 vs notAccepted:1.1.11、1.11、.1.1、1.1.1.1,无论如何......)。

考虑其他答案的不同之处在于,下面的代码不会以编程方式接受等于0.1.1,这实际上对用户更友好。它很简单,很适合我们。您只需将以下代码复制并粘贴到inputFormatters: []

如果你想同时接受0.1.1(不仅仅是0.1),你可以把FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*'))注释掉!

inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,2}')), FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')), ]

当您想更改最大小数点时,您可以在下面的行中更改N 的值:

inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^(\d+)?\.?\d{0,N}')), FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')), ]

第一个示例显示了您希望将小数点限制为 2 的情况,并且 N 值精确控制限制。您可以在自己的代码中尝试 [:

感谢所有其他答案,希望这个答案可以帮助未来的流浪者!祝你有美好的一天[:

【讨论】:

    【解决方案7】:

    对你来说可能有点晚了,但我也进步了一点:

    1. 只允许 1 个.
    2. 允许否定
    3. 在开头放置负号

    希望对你有帮助;)

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

    (别忘了导入上一个类)

    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),
          ],
        );
      }
    }
    

    【讨论】:

      【解决方案8】:

      也许这是一个更简单的解决方案

      inputFormatters: [
                  FilteringTextInputFormatter.allow(RegExp(r'(^\d*\.?\d{0,2})'))
                ]
      

      【讨论】:

      • 你能指定使用正则表达式的其他答案有什么更好的地方吗?
      • 某些语言使用逗号代替
      【解决方案9】:

      我扩展了功能......我希望你能发现它有用。请告诉我您是否可以进一步改进。

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

      【讨论】:

      • 这里的解决方案非常好。我认为如果在格式化数千位时包含逗号会更好。
      • 您好,先生!可以使用decimalRange max 2向您的代码添加数字格式吗?我想实现这个:“100.25”“1,000.25”“10,000.25”
      【解决方案10】:

      @AjayKumar 的答案允许将文本输入限制为所需的小数位。但我的要求是避免键盘中出现除数字和点之外的其他字符。所以,我更新了@AjayKumar 的上述答案

      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;
      

      } }

      【讨论】:

        【解决方案11】:

        并避免不必要的零...请调试此代码。

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

        【讨论】:

          【解决方案12】:

          我认为这是最简单也是唯一适合我的方法:

          inputFormatters: [ LengthLimitingTextInputFormatter(2), ]

          【讨论】:

          • 问题是限制用户输入超过两个“十进制数字”。给定的代码限制输入超过 2 个字符。完全不同的东西。
          【解决方案13】:

          对于Flutter 中的TextFeild,带有小数点前和小数点后长度验证 类。

          import 'package:flutter/cupertino.dart';
          import 'package:flutter/services.dart';
          import 'dart:math' as math;
          
          class DecimalTextInputFormatter extends TextInputFormatter {
            DecimalTextInputFormatter({this.decimalRange,this.beforeDecimalRange})
                : assert(decimalRange == null || decimalRange > 0 || beforeDecimalRange == null || beforeDecimalRange > 0 );
          
            final int decimalRange;
            final int beforeDecimalRange;
          
            @override
            TextEditingValue formatEditUpdate(
                TextEditingValue oldValue, // unused.
                TextEditingValue newValue,
                ) {
              TextSelection newSelection = newValue.selection;
              String truncated = newValue.text;
          
              String value;
          
              if(beforeDecimalRange != null){
                value = newValue.text;
          
                if(value.contains(".")){
                  if(value.split(".")[0].length > beforeDecimalRange){
                    truncated = oldValue.text;
                    newSelection = oldValue.selection;
                  }
                }else{
                  if(value.length > beforeDecimalRange){
                    truncated = oldValue.text;
                    newSelection = oldValue.selection;
                  }
                }
              }
          
              if (decimalRange != null) {
                value = newValue.text;
          
                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;
            }
          }    
          

          在 TextField 中, 前任。小数点前 9 位和小数点后 2 位允许的代码如下。

          inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}')),
                             DecimalTextInputFormatter(decimalRange: 2, beforeDecimalRange: 9)
                           ],
          keyboardType: TextInputType.numberWithOptions(decimal: true),
          

          【讨论】:

            【解决方案14】:

            这对我有用(2022 年 2 月)

            将文本限制为 2 个小数点,并且只有 1 个 '.' (句号)

            如果用户手动删除 '.' 之前的数字,0 将自动添加到数字的开头。

            PS:对答案稍作修改

            TextFormField

            TextFormField(
                      autofocus: false,
                      keyboardType: TextInputType.number,
                      controller: controller,
                      inputFormatters: [
                        DecimalTextInputFormatter(decimalRange: 2),
                      ],
                      validator: (value) {
                        if (value == null || value.isEmpty) {
                          return 'Please add amount.';
                        }
                        return null;
                      },
            

            DecimalTextInputFormatter

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

            【讨论】:

              猜你喜欢
              • 2019-08-16
              • 2012-09-05
              • 2021-10-22
              • 2019-04-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多