dmz社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 860|回复: 2

[混合APP] flutter通过TextInputFormatter实现限制数字输入

[复制链接]
  • TA的每日心情
    奋斗
    2023-7-10 09:34
  • 签到天数: 36 天

    [LV.5]常住居民I

    88

    主题

    133

    帖子

    668

    积分

    荣誉会员

    积分
    668

    发表于 2023-3-13 23:22:47 | 显示全部楼层 |阅读模式

    本站资源全部免费,回复即可查看下载地址!

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    背景
    在开发中经常会遇到需要对输入的数字限制的需求,比如限制输入几位小数,或者只能输入整数,或者支持负数。。。


    实现类

    [JavaScript] 纯文本查看 复制代码
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    /*
     * @Author: zhudaihao
     * @Date: 2022/2/25
     * @Describe: 限制输入数字和小数后位数
     */
    class NumberInputLimit extends TextInputFormatter {
      ///输入字符的范围
      String inputScope;
    
      ///允许的小数位数
      final int? digit;
    
      ///允许的最大值
      final double? max;
    
      ///是否支持 false不支持负数(默认不支持)
      final bool isNegative;
    
      NumberInputLimit({
        this.inputScope = '-.0123456789',
        this.digit,
        this.max,
        this.isNegative = false,
      });
    
      ///获取value小数点后有几位
      static int getDecimalAfterLength(String value) {
        if (value.contains(".")) {
          return value.split(".")[1].length;
        } else {
          return 0;
        }
      }
    
      @override
      TextEditingValue formatEditUpdate(
          TextEditingValue oldValue, TextEditingValue newValue) {
        //上次文本
        String oldContent = oldValue.text;
        //最新文本
        String newContent = newValue.text;
        //上次文本长度
        int oldLength = oldContent.length;
        //最新文本长度
        int newLength = newContent.length;
        //上次文本光标位置
        int oldBaseOffset = oldValue.selection.baseOffset;
        //最新文本光标位置
        int newBaseOffset = newValue.selection.baseOffset;
        //光标位置
        int offset = newBaseOffset;
    
        if (newLength > oldLength) {
          //输入的字符
          String inputContent = newContent.substring(oldBaseOffset, newBaseOffset);
          if (!isNegative) {
            inputScope = inputScope.replaceAll("-", "");
          }
          if (inputScope.contains(inputContent)) {
            if (oldLength > 0) {
              if ((max != null && double.parse(newContent) > max!) ||
                  (digit != null && getDecimalAfterLength(newContent) > digit!)) {
                newContent = oldContent;
                offset = oldBaseOffset;
              } else if (oldContent.substring(0, 1) == "-") {
                //上次文本首字符是-
                if ((oldContent.contains(".") && inputContent == ".") ||
                    inputContent == "-" ||
                    (oldContent.contains(".") &&
                        newLength > 2 &&
                        newContent.substring(2, 3) != "." &&
                        newContent.substring(1, 2) == "0") ||
                    (newLength > 2 && newContent.substring(0, 3) == "-00") ||
                    (newLength > 2 &&
                        !newContent.contains(".") &&
                        newContent.substring(1, 2) == "0") ||
                    (oldContent.substring(0, 1) == "-" &&
                        newContent.substring(0, 1) != "-")) {
                  newContent = oldContent;
                  offset = oldBaseOffset;
                }
              } else if (oldContent.substring(0, 1) == "0") {
                //上次文本首字符是0
                if (newLength > 1 && newContent.substring(0, 2) == "00" ||
                    (newContent.contains("-") &&
                        newContent.substring(0, 1) != "-") ||
                    (oldContent.contains(".") && inputContent == ".") ||
                    (newContent.substring(0, 1) == "0" &&
                        newLength > 1 &&
                        newContent.substring(1, 2) != ".")) {
                  newContent = oldContent;
                  offset = oldBaseOffset;
                }
              } else if (newContent.contains(".")) {
                //上次文本首字符是.
                if ((oldLength > 1 &&
                    oldContent.substring(0, 2) == "0." &&
                    inputContent == ".") ||
                    (newContent.substring(0, 1) != "-" &&
                        newContent.contains("-")) ||
                    (oldContent.contains(".") && inputContent == ".") ||
                    (oldContent.contains(".") &&
                        oldContent.substring(0, 1) != "." &&
                        newContent.substring(0, 1) == "0")) {
                  newContent = oldContent;
                  offset = oldBaseOffset;
                }
              }
            }
          } else {
            //输入限制范围外字符
            newContent = oldContent;
            offset = oldBaseOffset;
          }
        }
    
        return TextEditingValue(
          text: newContent,
          selection: TextSelection.collapsed(offset: offset),
        );
      }
    }



    使用代码
    [JavaScript] 纯文本查看 复制代码
    Scaffold(
      appBar: AppBar(
        title: const Text("测试编辑限制"),
      ),
      body: Material(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text("不限制"),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                decoration: const InputDecoration(hintText: "请输入"),
                inputFormatters: [
                  NumberInputLimit(),
                ],
              ),
            ),
            const Text("支持负数"),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                decoration: const InputDecoration(hintText: "请输入"),
                inputFormatters: [
                  //限制小数位数
                  NumberInputLimit(
                    isNegative: true,
                  ),
                ],
              ),
            ),
            const Text("限制输入最大值100"),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                decoration: const InputDecoration(hintText: "请输入"),
                inputFormatters: [
                  //限制小数位数
                  NumberInputLimit(
                    max: 100,
                  ),
                ],
              ),
            ),
            const Text("限制输入小数点2位"),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                decoration: const InputDecoration(hintText: "请输入"),
                inputFormatters: [
                  //限制小数位数
                  NumberInputLimit(
                    digit: 2,
                  ),
                ],
              ),
            ),
            const Text("限制输入所有字符范围"),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                decoration: const InputDecoration(hintText: "请输入"),
                inputFormatters: [
                  //限制小数位数
                  NumberInputLimit(
                    inputScope: "123456",
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    )

    温馨提示:
    1、本站所有内容均为互联网收集或网友分享或网络购买,本站不破解、不翻录任何视频!
    2、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意!
    3、本站资源仅供本站会员学习参考,不得传播及用于其他用途,学习完后请在24小时内自行删除.
    4、本站资源质量虽均经精心审查,但也难保万无一失,若发现资源有问题影响学习请一定及时点此进行问题反馈,我们会第一时间改正!
    5、若发现链接失效了请联系管理员,管理员会在2小时内修复
    6、如果有任何疑问,请加客服QQ:1300822626 2小时内回复你!
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    4 小时前
  • 签到天数: 1376 天

    [LV.10]以坛为家III

    0

    主题

    2865

    帖子

    9165

    积分

    超凡入圣

    Rank: 10Rank: 10Rank: 10

    积分
    9165

    发表于 2023-3-15 08:28:17 | 显示全部楼层
    1111111111111111
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    4 小时前
  • 签到天数: 1376 天

    [LV.10]以坛为家III

    0

    主题

    2865

    帖子

    9165

    积分

    超凡入圣

    Rank: 10Rank: 10Rank: 10

    积分
    9165

    发表于 2023-3-26 08:30:19 | 显示全部楼层
    44444444444444444
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|小黑屋|本站代理|dmz社区

    GMT+8, 2024-4-26 04:12 , Processed in 0.119926 second(s), 34 queries .

    Powered by Discuz! X3.4 Licensed

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表