需求
Flutter 实现一个文本输入框,能够计算word的数量,当超过最大数量时,文本框不再输入。
分析
Flutter文本框选用TextField,从"word的数量",想到可以使用LengthLimitingTextInputFormatter
, 但是这个formatter并不符合要求,因此需要重新实现下。
实现
MaxWordTextInputFormater.dart
class MaxWordTextInputFormater extends TextInputFormatter {
final int maxWords;
final ValueChanged<int>? currentLength;
MaxWordTextInputFormater({this.maxWords = 1, this.currentLength});
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
int count = 0;
if (newValue.text.isEmpty) {
count = 0;
} else {
count = newValue.text.trim().split(RegexUtil.spaceOrNewLine).length;
}
if (count > maxWords) {
return oldValue;
}
currentLength?.call(count);
return newValue;
}
}
TextFieldPage.dart
class TextFieldPage extends StatefulWidget {
const TextFieldPage({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return TextFieldPageState();
}
}
class TextFieldPageState extends State<TextFieldPage> {
final Color _color = const Color(0xFFF5F6F7);
int _count = 0;
final int maxWordLength = 6;
@override
Widget build(BuildContext context) {
return buildPage(
_buildBody(),
const Text(
"TextField Max Words Limit",
style: TextStyle(fontSize: 16, color: Colors.black),
));
}
Widget _buildBody() {
return Container(
color: _color,
child: Column(children: [
const SizedBox(
height: 12,
),
_buildTextField()
]));
}
Widget _buildTextField() {
return _buildContain(
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
"TextField",
style: TextStyle(fontSize: 16, color: Colors.black),
),
_buildCompute(),
],
),
TextInputFieldWidget(
textInputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r"[a-z\s_-]+")),
MaxWordTextInputFormater(maxWords: 6, currentLength: chageCount)
],
hintText: "please fill words ",
maxLines: 4,
lineHeight: 1.5,
)
],
),
);
}
Widget _buildCompute() {
return RichText(
text: TextSpan(
style: const TextStyle(fontSize: 14, color: Color(0xFF909399)),
children: [
const TextSpan(text: '('),
TextSpan(
text: _count.toString(),
style: TextStyle(
color: _count > 0
? const Color(0xFF5269FF)
: const Color(0xFF909399))),
TextSpan(text: "/${maxWordLength.toString()})"),
]));
}
void chageCount(int count) {
setState(() {
_count = count;
});
}
Scaffold buildPage(
Widget body,
Widget? titleWidget,
) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: 40,
backgroundColor: _color,
// status bar color
automaticallyImplyLeading: false,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarColor: _color, statusBarIconBrightness: Brightness.dark),
foregroundColor: _color,
shadowColor: Colors.transparent,
title: titleWidget,
),
body: SafeArea(
child: body,
),
);
}
Widget _buildContain(Widget child) {
return Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.only(left: 16, right: 16, top: 12),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(12))),
child: child);
}
}
效果图
Oct-18-2021 16-53-14.gifsourcecode
https://github.com/sayhellotogithub/textfield_length_limit_word
参考
https://api.flutter.dev/flutter/material/TextField-class.html
网友评论