【问题标题】:Flutter TextField maxLength not enforcedFlutter TextField maxLength 未强制执行
【发布时间】:2020-10-14 14:43:50
【问题描述】:

我正在实现两个简单的对话框,以允许用户在我的应用程序中编辑两个设置。从代码中可以看出,它们非常相似。 第一个,用于输入一个5位数字(我后面把String转成数字):

var tfController = TextEditingController();
String newPort = await showDialog<String>(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        content: Center(
            heightFactor: 1,
            child: TextField(
              controller: tfController,
              keyboardType: TextInputType.number,
              maxLength: 5,
              autofocus: true,
              decoration: InputDecoration(labelText: "Insert number:"), 
              onEditingComplete: () {
                Navigator.of(context).pop(tfController.text);
              },
            )),
        actions: [
          FlatButton(
            child: Icon(Icons.done),
            onPressed: () {
              Navigator.of(context).pop(tfController.text);
            },
          ),
          FlatButton(
              child: Icon(Icons.clear),
              onPressed: () {
                Navigator.of(context).pop();
              })
        ],
      );
    });

第二个对话框,一个通用的文本输入:

var tfController = TextEditingController();
String newHeader = await showDialog<String>(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        content: Center(
            heightFactor: 1,
            child: TextField(
              controller: tfController,
              keyboardType: TextInputType.text,
              maxLength: 30,
              maxLengthEnforced: true, //added later even if it's true by default, doesn't change anything
              autofocus: true,
              decoration: InputDecoration(labelText: "Insert text:"),
              onEditingComplete: () {
                Navigator.of(context).pop(tfController.text);
              },
            )),
        actions: [
          FlatButton(
            child: Icon(Icons.done),
            onPressed: () {
              Navigator.of(context).pop(tfController.text);
            },
          ),
          FlatButton(
              child: Icon(Icons.clear),
              onPressed: () {
                Navigator.of(context).pop();
              })
        ],
      );
    });

第一个对话框完美地工作:当需要时,它会弹出已经聚焦的字段,键盘只显示数字,并且输入自动限制为长度 5,正如预期的那样。因此,当我需要用户输入有限的文本字符串时,我只是复制了代码,只更改了长度。 一切似乎都运行良好,所以起初我什至懒得检查maxLength 是否被强制执行:我才发现,很久以后,第二个对话框允许用户超过最大长度,尽管它正确地改变了提示的颜色和下划线为红色,让用户知道有问题。

我知道我可以很容易地为此设置一个解决方法,例如在用户确认输入后截断字符串,但问题更多是关于为什么这两个对话框的行为不同于如何解决这个问题强>.

【问题讨论】:

    标签: flutter textfield maxlength


    【解决方案1】:

    我不确定它是否有效,我使用maxLength 遇到了同样的问题,我已经通过使用inputFormatters 属性解决了它。以下代码会将 textFormField 的长度限制为 30:

    先导入包import 'package:flutter/services.dart';

    new TextField(
      inputFormatters: [
        new LengthLimitingTextInputFormatter(30),
      ],
    ),
    

    【讨论】:

    • 我知道如何解决这个问题并且只获取前 30 个字符。我的问题是关于为什么第一个对话框不需要 inputFormatter,而第二个对话框却需要
    【解决方案2】:

    您应该仔细阅读official document

    ma​​xLength 属性

    文本字段中允许的最大字符数(Unicode 标量值)。

    如果设置,字符计数器将显示在字段下方,显示已输入的字符数。如果设置为大于 0 的数字,它还将显示允许的最大数字。如果设置为 TextField.noMaxLength 则仅显示当前字符数。

    输入 maxLength 个字符后,其他输入将被忽略,除非 maxLengthEnforced 设置为 false。文本字段使用 LengthLimitingTextInputFormatter 强制长度,该长度在提供的 inputFormatters(如果有)之后进行评估。

    此值必须为 null、TextField.noMaxLength 或大于 0。如果为 null(默认值),则可以输入的字符数没有限制。如果设置为 TextField.noMaxLength,则不会强制执行任何限制,但仍会显示输入的字符数。

    空白字符(例如换行符、空格、制表符)包含在字符数中。

    如果 maxLengthEnforced 设置为 false,则可以输入超过 maxLength 个字符,但错误计数器和分隔符会在超出限制时切换到装饰的 InputDecoration.errorStyle。

    限制 文本字段当前不计算 Unicode 字素簇(即用户可见的字符),它计算 Unicode 标量值,这会遗漏一些有用的可能字符(如许多表情符号和组合字符),因此这在这些角色的存在。如果您预计会遇到这些类型的字符,请在使用的 maxLength 方面大方。

    例如,字符“ö”可以表示为'\u{006F}\u{0308}',即字母“o”后跟一个组合分音符号“¨”,也可以表示为'\u{00F6}',它是 Unicode 标量值“LATIN SMALL LETTER O WITH DIAERESIS”。在第一种情况下,文本字段将计入两个字符,而在第二种情况下将计入一个字符,即使用户在输入中看不到任何差异。

    同样,一些表情符号由多个标量值表示。 Unicode“竖起大拇指+中等肤色修饰符”,“??”,应该算作单个字符,但是因为它是两个Unicode标量值的组合,'\u{1F44D}\u{1F3FD}' , 算作两个字符。

    Here 是您正在寻找的。 @Assassin 有一个很好的答案。

    【讨论】:

    • 正如我上面评论的,我不需要将输入截断为 30 个字符的方法。我想了解为什么第一个对话框不需要 inputFormatter (或任何其他解决方案),而第二个对话框则需要。除非我在文档中仍然缺少某些东西,否则我看不到有关这种不同行为原因的任何提示
    【解决方案3】:

    这个问题变得无关紧要,因为 maxLengthEnforced 参数已被弃用,并已被替换为 maxLengthEnforcement,后者具有更复杂的行为。

    【讨论】:

      【解决方案4】:

      需要升级到flutter 1.22.6

      在控制台中编写命令:

      flutter version 1.22.6
      

      【讨论】:

        猜你喜欢
        • 2020-05-20
        • 2013-02-08
        • 2013-06-30
        • 2011-03-02
        • 2021-09-26
        • 2017-07-21
        • 2021-07-12
        相关资源
        最近更新 更多