【问题标题】:Flutter multiline with max lines具有最大行数的颤振多行
【发布时间】:2020-04-13 02:31:57
【问题描述】:

我正在使用具有以下属性的文本字段:

 TextField(
    controller: textController,    
    keyboardType: TextInputType.multiline,
    maxLines: 4,
    maxLength: 150,
 ),

这很好,但我想知道如何防止用户输入会导致文本字段的行数超过 maxLines (4)..

有没有办法将行锁定在 4 处? 例如

输入 1 \n \n \n 应该可以工作

但是 1 \n \n \n \n \n \n 不应该被允许

【问题讨论】:

    标签: flutter


    【解决方案1】:

    我修改了LengthLimitingTextInputFormatter 以获得我自己的MaxLinesTextInputFormatter

    这里是代码

    class MaxLinesTextInputFormatter extends TextInputFormatter {
      MaxLinesTextInputFormatter(this.maxLines)
          : assert(maxLines == null || maxLines == -1 || maxLines > 0);
    
      final int maxLines;
    
      @override
      TextEditingValue formatEditUpdate(
        TextEditingValue oldValue, // unused.
        TextEditingValue newValue,
      ) {
        if (maxLines != null && maxLines > 0) {
          final regEx = RegExp("^.*((\n?.*){0,${maxLines - 1}})");
          String newString = regEx.stringMatch(newValue.text) ?? "";
    
          final maxLength = newString.length;
          if (newValue.text.runes.length > maxLength) {
            final TextSelection newSelection = newValue.selection.copyWith(
              baseOffset: math.min(newValue.selection.start, maxLength),
              extentOffset: math.min(newValue.selection.end, maxLength),
            );
            final RuneIterator iterator = RuneIterator(newValue.text);
            if (iterator.moveNext())
              for (int count = 0; count < maxLength; ++count)
                if (!iterator.moveNext()) break;
            final String truncated = newValue.text.substring(0, iterator.rawIndex);
            return TextEditingValue(
              text: truncated,
              selection: newSelection,
              composing: TextRange.empty,
            );
          }
          return newValue;
        }
        return newValue;
      }
    }
    

    用法:

    TextField(
      decoration: InputDecoration(),
      maxLines: 4,
      inputFormatters: [MaxLinesTextInputFormatter(4)],
    )
    

    【讨论】:

    • 输入表情就不行了
    【解决方案2】:

    您可以使用allMatches() 函数计算输入包含的行数,如果函数返回 4 或更多,则更新错误变量。

    if (('\n'.allMatches(text).length + 1) > 4) { // check for new lines and update bool variable }
    

    一个例子:

    import 'package:flutter/material.dart';
    
    class Demo extends StatefulWidget {
      @override
      _DemoState createState() => _DemoState();
    }
    
    class _DemoState extends State<Demo> {
      final textController = TextEditingController();
    
      bool error = false;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("DEMO"),
            ),
            body: Container(
                child: Column(children: [
              TextField(
                controller: textController,
                keyboardType: TextInputType.multiline,
                maxLines: 4,
                maxLength: 150,
                onChanged: (text) {
                  setState(() {
                    if (('\n'.allMatches(text).length + 1) > 4) {
                      error = true;
                    } else {
                      error = false;
                    }
                  });
                },
              ),
              error ? Text("More than 4 lines entered") : Container()
            ])));
      }
    }
    

    【讨论】:

      【解决方案3】:

      我将 Crazy Lazy Cat 的答案更新为 null 安全

      import 'dart:math';
      
      import 'package:flutter/services.dart';
      
      class MaxLinesTextInputFormatter extends TextInputFormatter {
        MaxLinesTextInputFormatter(this._maxLines) : assert(_maxLines == -1 || _maxLines > 0);
      
        final int _maxLines;
      
        @override
        TextEditingValue formatEditUpdate(
          TextEditingValue oldValue, // unused.
          TextEditingValue newValue,
        ) {
          if (_maxLines > 0) {
            final regEx = RegExp("^.*((\n?.*){0,${_maxLines - 1}})");
            final newString = regEx.stringMatch(newValue.text) ?? "";
            final maxLength = newString.length;
            if (newValue.text.runes.length > maxLength) {
              final newSelection = newValue.selection.copyWith(
                baseOffset: min(newValue.selection.start, maxLength),
                extentOffset: min(newValue.selection.end, maxLength),
              );
              final iterator = RuneIterator(newValue.text);
              if (iterator.moveNext()) {
                for (var count = 0; count < maxLength; ++count) {
                  if (!iterator.moveNext()) break;
                }
              }
              final truncated = newValue.text.substring(0, iterator.rawIndex);
              return TextEditingValue(
                text: truncated,
                selection: newSelection,
                composing: TextRange.empty,
              );
            }
            return newValue;
          }
          return newValue;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-12-20
        • 2021-10-22
        • 2019-03-30
        • 2020-09-27
        • 2020-06-23
        • 2021-07-11
        • 2020-11-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多