You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:42:45