Flutter嵌套ListView内TextField输入值父列表全项重复问题求解
问题原因
- 你为内部
GridView设置了UniqueKey(),每次组件重绘时key都会变更,导致整个GridView直接重建,内部TextField的状态丢失,Flutter在复用组件时无法正确匹配对应位置的输入框,最终出现数据串位。 - 没有为每个TextField绑定独立的
TextEditingController,仅靠onChanged回调在组件重建时容易出现数据错乱。 - 大概率你初始化
List<List<Object>>结构时复用了同一个Map对象的引用,修改某一项的值会同步到所有引用该对象的位置,导致所有父项拿到相同数据。
修复步骤
- 删除GridView的UniqueKey
如果需要为GridView设置key,改为和位置绑定的ValueKey即可:
GridView.builder( // 删掉原来的key: UniqueKey(), key: ValueKey(parentindex), // 其余属性不变 )
- 初始化二维TextEditingController数组
在State的initState中按照数据结构创建对应数量的控制器,每个输入框绑定独立控制器,避免状态混淆:
late List<List<TextEditingController>> _inputControllers; @override void initState() { super.initState(); _inputControllers = widget.workoutExercise.intensityPart.map((parentItem) { return parentItem.map((childItem) { return TextEditingController(text: childItem['value'].toString()); }).toList(); }).toList(); } @override void dispose() { // 释放控制器资源 for (var parentList in _inputControllers) { for (var controller in parentList) { controller.dispose(); } } super.dispose(); }
- 为TextField绑定对应控制器
修改textItem方法中的TextField配置,同时删除TextField的UniqueKey,换成位置绑定的ValueKey:
TextField( // 删掉原来的key: UniqueKey(), key: ValueKey('input_${parentindex}_$index'), controller: _inputControllers[parentindex][index], // 其余属性保持不变 )
- 检查数据初始化逻辑
确保你创建intensityPart结构时,每个子项的Map都是独立的新对象,不要复用同一个引用:
// 错误写法:所有子项引用同一个Map,修改任意项全量同步 Map template = {"title": "重量", "value": ""}; for(int i=0; i<5; i++){ childList.add(template); } // 正确写法:每次创建新的Map对象 for(int i=0; i<5; i++){ childList.add({"title": "重量", "value": ""}); }
- 数据读取优化
如果不需要实时保存输入内容,可以在最终提交时统一遍历控制器数组获取所有输入值,比每次onChanged回调写入性能更高:
void saveAllData(){ for(int parentIdx = 0; parentIdx < _inputControllers.length; parentIdx++){ for(int childIdx = 0; childIdx < _inputControllers[parentIdx].length; childIdx++){ String inputText = _inputControllers[parentIdx][childIdx].text; widget.workoutExercise.intensityPart[parentIdx][childIdx]['value'] = inputText; } } }
内容的提问来源于stack exchange,提问作者Meet Parsaniya
相关产品推荐
相关产品推荐

