Flutter中ListView内TextFormField点击按钮后丢失输入值问题
问题原因及解决方案
核心问题
输入值丢失的根源在TaxDetailItem的build方法中:
textEditingController.value = TextEditingValue(text: taxResidence.id);
每次Widget重建(比如点击增删按钮触发setState)时,这行代码都会强制把输入框的值重置为taxResidence.id的初始值,直接覆盖用户输入的内容。
分步解决
1. 删除build方法中的强制赋值代码
直接移除TaxDetailItem里的这行代码,避免每次重建都重置输入框内容:
// 删掉这一行 // textEditingController.value = TextEditingValue(text: taxResidence.id);
2. 初始化控制器时设置初始值
不管是初始化列表还是新增项,都在创建TextEditingController时设置初始值,而非在build阶段:
列表初始化时:
// 替换原有的controllers初始化逻辑 controllers = taxResidencyList .map((taxItem) => TextEditingController(text: taxItem.id)) .toList();新增列表项时(BlocListener内):
if (state is AddNewTaxCountryState) { taxResidencyList.add(state.taxResidence); // 创建控制器时直接传入初始值 TextEditingController controller = TextEditingController(text: state.taxResidence.id); controllers.add(controller); setState(() {}); }
3. 同步输入值到数据源(可选但关键)
为保证用户输入的Tax ID能同步到taxResidencyList(比如后续提交表单时获取最新值),给TextFormField添加onChanged回调:
TextFormField( decoration: const InputDecoration( contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 5), hintText: 'Tax ID or N/A'), controller: textEditingController, // 添加输入同步逻辑 onChanged: (value) { // 若taxResidence是可变对象,直接更新id taxResidence.id = value; // 若taxResidence是不可变对象,需通过索引替换列表项 // final updatedItem = taxResidence.copyWith(id: value); // setState(() { taxResidencyList[index] = updatedItem; }); }, )
额外注意事项
移除列表项时,需同时销毁并移除对应的控制器,避免内存泄漏:
void removeTaxCountry(int index) { setState(() { taxResidencyList.removeAt(index); controllers[index].dispose(); controllers.removeAt(index); }); }
内容的提问来源于stack exchange,提问作者mars_dev
相关产品推荐
相关产品推荐

