Flutter文本框只允许输入十进制数字。

33
我希望在 Flutter 中的 TextField 中仅输入十进制数字。 我尝试了以下代码,但它并没有起作用。 它允许输入字母(a-z)和特殊字符。
TextField(
  controller:
      new TextEditingController(text: listDisplay[position].getBlockQty(),
  ),       
  textAlign: TextAlign.center,
  maxLines: 1,       
  keyboardType: TextInputType.numberWithOptions(
      decimal: true,
      signed: false),       
),

对我来说这个是有效的。你所说的alpha works是什么意思? - Mangaldeep Pannu
Alpha(A-Z)并且允许特殊字符,如+,-。 - Sagar Zala
它允许使用字母单词”是什么意思?它会显示出来,但是不能点击。 - CopsOnRoad
你能否同时包含你想要的和你得到的截图? - CopsOnRoad
1
@CopsOnRoad,我正在使用硬件键盘输入数据。那是问题吗? - Sagar Zala
显示剩余4条评论
7个回答

42
尝试这个:
inputFormatters: [
  FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
  TextInputFormatter.withFunction((oldValue, newValue) {
    final text = newValue.text;
    return text.isEmpty
        ? newValue
        : double.tryParse(text) == null
            ? oldValue
            : newValue;
  }),
],

演示:

TextFormField(
  keyboardType: TextInputType.numberWithOptions(
    decimal: true,
    signed: false,
  ),
  onChanged: _yourOnChange,
  inputFormatters: [
    FilteringTextInputFormatter.allow(RegExp(r"[0-9.]")),
    TextInputFormatter.withFunction((oldValue, newValue) {
      final text = newValue.text;
      return text.isEmpty
          ? newValue
          : double.tryParse(text) == null
              ? oldValue
              : newValue;
    }),
  ],
)

19

您可以使用TextInputFormatter来处理此情况。

这是一个相同情况的示例,

子类化TextInputFormatter

import 'package:flutter/services.dart';

class RegExInputFormatter implements TextInputFormatter {
  final RegExp _regExp;

  RegExInputFormatter._(this._regExp);

  factory RegExInputFormatter.withRegex(String regexString) {
    try {
      final regex = RegExp(regexString);
      return RegExInputFormatter._(regex);
    } catch (e) {
      // Something not right with regex string.
      assert(false, e.toString());
      return null;
    }
  }

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final oldValueValid = _isValid(oldValue.text);
    final newValueValid = _isValid(newValue.text);
    if (oldValueValid && !newValueValid) {
      return oldValue;
    }
    return newValue;
  }

  bool _isValid(String value) {
    try {
      final matches = _regExp.allMatches(value);
      for (Match match in matches) {
        if (match.start == 0 && match.end == value.length) {
          return true;
        }
      }
      return false;
    } catch (e) {
      // Invalid regex
      assert(false, e.toString());
      return true;
    }
  }
}

将其与您的文本字段一起使用

final _amountValidator = RegExInputFormatter.withRegex('^\$|^(0|([1-9][0-9]{0,}))(\\.[0-9]{0,})?\$');
...
TextField(
  inputFormatters: [_amountValidator],
  keyboardType: TextInputType.numberWithOptions(
    decimal: true,
     signed: false,
   ),
 )

2
对于限制:RegExInputFormatter.withRegex('^ [0-9] {0,6}(\。[0-9] {0,2})?$') - Adem Aygun
这适用于小数分隔符为逗号而不是句点的地区吗? - CodeGrue
我没有尝试过那个。但我相信你需要更新正则表达式。 - Johnykutty
@Johnykutty 在满足以上所有要求的同时,我还想允许负数。正则表达式需要做哪些更改? - Dhaval Kansara
@DhavalKansara,你可以在正则表达式的开头添加“([-]{0,1})”。类似于“^$|^(0|([1-9][0-9]{0,}))(\.[0-9]{0,})?$”。 PS:我没有在代码中尝试过这个正则表达式,只是在https://www.regexpal.com上尝试了一下。 - Johnykutty

9

我正在使用这个代码,但在一些手机上只显示数字,在其他手机上则显示破折号和其他字符,结果似乎取决于启动器或类似的东西,在iPhone上应该会显示正确的键盘(我已经在iPhone 7s plus上尝试过)。

inputFormatters将只允许数字输入,因此您将得到想要的结果。

   TextField(
     textAlign: TextAlign.start,
     keyboardType: TextInputType.numberWithOptions(decimal: true),
     inputFormatters: <TextInputFormatter>[
                          FilteringTextInputFormatter.digitsOnly
                       ],
   ),

7
FilteringTextInputFormatter.digitsOnly 只允许输入数字,不允许输入逗号或句号。 - Albert221

4

我也曾经寻找这个问题的答案,通过多次尝试和努力终于找到了。

你可以使用这个正则表达式来匹配十进制数。

inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r'^[0-9]+.?[0-9]*'))
      ],

好的!它也可以工作。 - Sagar Zala
很棒的答案,一个优化是在正则表达式中使用\.。例如r'^[0-9]+\.?[0-9]*'因为.在正则表达式中可以代表任何单个字符,就像123:1 - Neo Liu
没有花很多时间在这上面,但是那个正则表达式对于空格和多个句号来说都让我通过了。而且,我希望小数位数是可选的。我在一个能捕捉到空格和多个句号的JavaScript正则表达式答案中找到了这个:请尝试以下表达式:^\d+.\d{0,2}$ 如果你想使小数位数是可选的,可以使用以下表达式:^\d+(.\d{1,2})?$ - user1544428
请将文本从英文翻译成中文。只返回翻译后的文本:请记得在正则表达式中使用^和$,以便hasMatch()方法能够正确匹配完整的输入文本:^[0-9]+.?[0-9]*$,并且不会通过像4..这样的情况。 - undefined

3
添加 inputFormatters 行:
 TextField(
     inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))],
          ...)

1

我在我的一个项目中使用了这段代码,它运行得很好。希望它能对你有所帮助。

TextField(
         decoration: InputDecoration(
         border: InputBorder.none,
         hintText: "Amount",
         hintStyle:
         TextStyle(color: Colors.grey, fontSize: 12.0),
         ),
         style: TextStyle(color: Colors.black, fontSize: 12.0),
         controller: _amountController[index],
         textInputAction: TextInputAction.done,
         keyboardType: TextInputType.numberWithOptions(decimal: true),)

enter image description here


2
TextInputType.numberWithOptions 不起作用。我已经在问题中提到了。 - Sagar Zala
@SagarZala 我已经添加了屏幕。你可以看到它的工作。 - Sunny
在华为Mate 20 Pro上,我发现有些字符和数字都无法正常显示。 - lacas
仅仅使用TextInputType.numberWithOptions(decimal: true)是不够的。它会允许输入12.123.121这样的类型。 - saurabhlahoti

0
尝试这个十进制的函数
import 'package:flutter/services.dart';
...
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp('[0-9.,]+')),],
onChanged: (value) => doubleVar = double.parse(value),

还有

RegExp('([0-9]+(.[0-9]+)?)') 用于允许数字和只有一个小数点


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接