最大行数颤振多行

时间:2019-12-20 15:19:48

标签: flutter

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

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

哪个可以正常工作,但是我想知道如何防止用户键入换行符,从而导致文本字段的行数超过maxLines(4)。

是否可以将行锁定在4? 例如

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

但是不允许1 \ n \ n \ n \ n \ n \ n

3 个答案:

答案 0 :(得分: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)],
)

答案 1 :(得分:0)

您可以使用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()
        ])));
  }
}

答案 2 :(得分:0)

我将 Crazy Lazy Cat 的答案更新为 null 安全性和 Effective Dart 标准

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;
  }
}