我正在使用具有以下属性的文本字段:
TextField(
controller: textController,
keyboardType: TextInputType.multiline,
maxLines: 4,
maxLength: 150,
),
哪个可以正常工作,但是我想知道如何防止用户键入换行符,从而导致文本字段的行数超过maxLines(4)。
是否可以将行锁定在4? 例如
输入1 \ n \ n \ n应该可以工作
但是不允许1 \ n \ n \ n \ n \ n \ n
答案 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;
}
}