Flutter如何在按钮点击时获取列表渲染的TextEditingController值
问题分析与解决方案
你的问题根源在于每次ListView.builder重建列表项时都会重新调用editableAdress(),这会重复创建TextEditingController实例,并且你添加到addressesList里的只是控制器的初始文本值,后续输入更新根本不会同步到列表里的对象。
要实现点击按钮时一次性获取所有输入值,不需要提前维护对象列表,只需要统一管理所有列表项的控制器即可,具体做法如下:
1. 统一管理控制器列表
在你的State类里定义一个存储控制器的列表,每个元素包含当前列表项的两个输入控制器:
// 用元组存储每组输入的两个控制器,也可以自定义类替代 List<({TextEditingController nameCtrl, TextEditingController secondNameCtrl})> _controllers = [];
2. 初始化控制器
在initState里根据列表长度(这里是6)初始化所有控制器,同时设置初始文本:
@override void initState() { super.initState(); // 假设你有一个初始地址列表addresses,长度为6 for (var i = 0; i < 6; i++) { final address = addresses[i]; // 替换成你的初始地址数据源 _controllers.add( ( nameCtrl: TextEditingController(text: address.adrName1), secondNameCtrl: TextEditingController(text: address.adrName2), ), ); } }
3. 修改列表项构建逻辑
把editableAdress()改成带控制器参数的方法,直接使用控制器列表中对应位置的实例:
ListView.builder( controller: _deviceScroll, itemCount: 6, itemBuilder: (BuildContext context, int index) { final ctrlGroup = _controllers[index]; return _editableAddress(ctrlGroup); }, ); // 接收外部传入的控制器,不再内部重复创建 Widget _editableAddress(({TextEditingController nameCtrl, TextEditingController secondNameCtrl}) ctrlGroup) { return Column( children: [ Text('NAME', style: headingStyle), const SizedBox(height: 10), Column( children: [ editableTextField(context, ctrlGroup.nameCtrl, 'Person 1 / Firma'), const SizedBox(height: 10), editableTextField(context, ctrlGroup.secondNameCtrl, 'Person 2'), ], ), ], ); }
4. 点击按钮获取所有值
在按钮的点击事件里,遍历控制器列表,直接读取每个控制器的text生成Address对象:
ElevatedButton( onPressed: () { // 一次性提取所有输入的最新值 final List<Address> allAddresses = _controllers.map((ctrls) { return Address( adrName1: ctrls.nameCtrl.text, adrName2: ctrls.secondNameCtrl.text, ); }).toList(); // 这里对allAddresses做后续业务处理 print(allAddresses); }, child: const Text('获取所有地址'), )
5. 释放控制器资源
记得在dispose里销毁所有控制器,避免内存泄漏:
@override void dispose() { for (var ctrls in _controllers) { ctrls.nameCtrl.dispose(); ctrls.secondNameCtrl.dispose(); } super.dispose(); }
方案优势
- 控制器仅在
initState创建一次,不会因列表项重建重复生成 - 所有控制器统一保存在State中,点击按钮时可直接获取最新输入文本
- 无需提前维护
addressesList,完全在需要时才生成目标对象列表
内容的提问来源于stack exchange,提问作者Salman Akbar
相关产品推荐
相关产品推荐

