dart 如何限制两点抖动?

ghhkc1vu  于 2023-01-10  发布在  其他
关注(0)|答案(6)|浏览(199)

我需要限制当用户类型1..像这样。我正在使用文本输入表单字段。我需要输入像1.23与十进制输入文本格式化程序

omvjsjqw

omvjsjqw1#

不建议使用白名单文本输入格式设置程序

TextField(
 keyboardType: TextInputType.numberWithOptions(decimal: true),
 inputFormatters: <TextInputFormatter>[
      FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d*')),
  ], // Only numbers can be entered
),
vd8tlhqk

vd8tlhqk2#

我们可以创建自己的TextInputFormatter
你看看这个

import 'package:flutter/services.dart';

class DecimalTextInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    final regEx = RegExp(r"^\d*\.?\d*");
    String newString = regEx.stringMatch(newValue.text) ?? "";
    return newString == newValue.text ? newValue : oldValue;
  }
}
    • 用法:**
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirstPage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class FirstPage extends StatefulWidget {
  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextField(
          inputFormatters: [DecimalTextInputFormatter()],
        ),
      ),
    );
  }
}
7d7tgy0s

7d7tgy0s3#

Flutter1.20更新

正如用户@ZaH提到的,WhitelistingTextInputFormatter在Flutter 1.20中已经被弃用,应该使用FilteringTextInputFormatter.allow()。查看ZaH的answer here并投赞成票。你可以找到classconstructor的文档。

TextFormField(
    inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r"\d+([\.]\d+)?")),
    ],
);

溶液
以下是您需要针对特定使用情形执行的操作:

TextFormField(
    inputFormatters: [
        WhitelistingTextInputFormatter(RegExp(r"\d+([\.]\d+)?")),
    ],
);

解释

您需要使用TextInputFormatter类,特别是WhitelistingTextInputFormatter
上面的代码只允许使用您在问题中提供的模式的数字。数字可以是任意数量的小数位数,允许有一个小数点。
字符串前面的r前缀(如r"")使字符串成为raw string。这将阻止过滤和处理字符串中的特殊字符。从docs
注意上面例子中的raw字符串(一个以r为前缀的字符串)的用法。使用raw字符串可以将字符串中的每个字符都视为字面字符。

Regex解剖

下面是对正则表达式模式^\d+([\.]\d+)?$的剖析:

  • \d数字--allows所有语言的数字。
  • +一次或多次出现。
  • (PATTERN)?零或一出现--这允许没有小数点/数字的数字。
  • [\.]允许点字符--\用于转义它,因为它是regex中的控制字符。

来源

l2osamch

l2osamch4#

om-ha的答案是正确的,但是为了便于将来参考,自1.20起,WhitelistingTextInputFormatter在Flutter中已弃用,现在我们应该使用FilteringTextInputFormatter.allow()来代替。
或者使用过滤文本输入格式设置程序.deny而不是黑名单文本输入格式设置程序(如果这是您想要的)。
以上代码应变为:

TextFormField(
     inputFormatters: [
       FilteringTextInputFormatter.allow(RegExp(r"\d+([\.]\d+)?")),
     ],
    );
brccelvz

brccelvz5#

你也可以在表单提交时尝试十进制验证。

bool isValidDecimal(String value){
    String regex = r'^[0-9]+[.]{1}[0-9]+$';
    RegExp regExp = RegExp(regex);
    return regExp.hasMatch(value);
  }
iyzzxitl

iyzzxitl6#

这将允许任何数字,使用特定于区域设置的十进制分隔符(afaik总是','或'.')。intl包用于获得该分隔符。

import 'package:intl/intl.dart';
...
TextFormField(
  inputFormatters: [
    TextInputFormatter.withFunction((oldValue, newValue) {
      var decimalSeparator = NumberFormat().symbols.DECIMAL_SEP;
      var r = RegExp(r'^\d*(\' + decimalSeparator + r'\d*)?$');
      return r.hasMatch(newValue.text) ? newValue : oldValue;
    })
  ],
...

顺便说一句,使用FilteringTextInputFormatter的答案将用于验证初始输入,但当试图将有效数字编辑为无效数字时,将显示奇怪的行为-一些字符将被覆盖,其他字符将被删除。
根据docs
请考虑使用不同的TextInputFormatter ...根据完整字符串上的 predicate 接受/拒绝新输入。例如,FilteringTextInputFormatter通常不应与包含位置匹配器(^或$)的RegExp一起使用,因为这些模式通常用于匹配整个字符串。

相关问题