Flutter动态分配正则表达式值问题求助
解决Flutter动态正则表达式传入FilteringTextInputFormatter失效问题
问题根源
你的核心问题出在数据模型中存储的正则表达式格式错误:
- 你在
acceptingString数组里存储的是带Dart原始字符串标记的内容(比如'r\'^[a-zA-Z0-9. ]*\''),但RegExp构造函数只需要纯正则表达式字符串,不需要r'和闭合的'。这些额外字符会导致正则表达式解析失败,匹配不到任何字符,所以TextField无法输入内容。 - 另外,你在循环内每次创建
TextEditingController,会导致setState重建时控制器被重置,输入的内容会丢失,这是额外的潜在问题。
解决方案
1. 修正数据模型中的正则字符串
将acceptingString里的内容改为纯正则表达式,去掉r'和':
List<ENP> namePlates = [ ENP( 'Order Details', [ 'Alpha-numeric, space and dot', 'Alpha-numeric and space', 'only numeric', 'only numeric' ], ['Model', 'Project Name', 'Order Number', 'Works Number'], [ r'^[a-zA-Z0-9. ]*', // 直接用Dart原始字符串(或写成'^[a-zA-Z0-9. ]*') r'^[a-zA-Z0-9 ]*', r'^[0-9]*', r'^[0-9]*' ], ) ];
注:这里的r''是Dart中定义原始字符串的语法,避免转义字符干扰,最终存储到数组的是纯粹的正则表达式内容。
2. 正确使用动态正则表达式
在_buildExpandableContent中直接使用修正后的字符串创建RegExp即可:
var allowedCharacters = namePlates[selectedENPIndex].acceptingString[i]; // 直接传入纯正则字符串初始化RegExp FilteringTextInputFormatter.allow(RegExp(allowedCharacters))
3. 修复TextEditingController的生命周期问题
不要在循环内每次创建新的TextEditingController,提前在State类中初始化控制器列表,避免重建时丢失输入内容:
// 在State类中定义控制器列表 List<TextEditingController> _controllers = []; @override void initState() { super.initState(); // 预创建所有需要的控制器 int totalFields = namePlates.fold(0, (sum, enp) => sum + enp.contents.length); _controllers = List.generate(totalFields, (_) => TextEditingController()); } @override void dispose() { // 释放所有控制器资源 for (var controller in _controllers) { controller.dispose(); } super.dispose(); }
在_buildExpandableContent中复用控制器:
List<Widget> _buildExpandableContent(int selectedENPIndex) { List<Widget> columnContent = []; // 计算当前ENP对应的控制器起始索引 int startIndex = 0; for (int i = 0; i < selectedENPIndex; i++) { startIndex += namePlates[i].contents.length; } for (int i = 0; i < namePlates[selectedENPIndex].contents.length; i++) { // 从列表中获取对应控制器,而非每次新建 TextEditingController dynamicController = _controllers[startIndex + i]; var allowedCharacters = namePlates[selectedENPIndex].acceptingString[i]; columnContent.add(Container( padding: const EdgeInsets.only(left: 50, right: 50, bottom: 10), child: TextFormField( maxLength: 16, inputFormatters: <TextInputFormatter>[ FilteringTextInputFormatter.allow(RegExp(allowedCharacters)) ], controller: dynamicController, decoration: InputDecoration( border: const UnderlineInputBorder(), labelText: namePlates[selectedENPIndex].contents[i], hintText: namePlates[selectedENPIndex].acceptingString[i], ), ), )); } columnContent.add(const Padding( padding: EdgeInsets.only(top: 20, bottom: 20), )); return columnContent; }
内容的提问来源于stack exchange,提问作者Microcad
相关产品推荐
相关产品推荐

