Flutter动态生成的TextEditingController无法更新text属性问题排查
根因分析
你在触发setState更新页面状态时,组件build方法会完整重走,此时textField方法会被重新调用,方法内部每次都会创建全新的TextEditingController实例绑定到新生成的TextFormField上。你之前点击输入框存储的_selectedField是旧版本的控制器实例,和重新渲染后输入框绑定的新控制器没有关联,所以给旧控制器的text属性赋值自然不会同步到当前页面的输入框上。
修复步骤
- 在State类中新增控制器存储列表,在
initState阶段提前完成所有控制器的初始化,不要在build过程中动态生成控制器:
class _MyHomePageState extends State<MyHomePage> { TextEditingController? _selectedField; // 存储所有输入框的控制器 late List<TextEditingController> _controllerList; @override void initState() { super.initState(); // 提前创建3个对应输入框的控制器 _controllerList = List.generate(3, (_) => TextEditingController()); } // 页面销毁时释放所有控制器,避免内存泄漏 @override void dispose() { for (var controller in _controllerList) { controller.dispose(); } super.dispose(); }
- 修改
textField方法,复用已有的控制器生成输入框,不要在方法内创建新控制器:
Column textField() { List<Widget> listForm = []; for (var textEditingController in _controllerList) { listForm.add( TextFormField( controller: textEditingController, onTap: () { debugPrint('Current Controller: $textEditingController'); setState(() { _selectedField = textEditingController; }); }, ), ); } return Column(children: listForm); }
- 修改build方法中调用
textField的代码,去掉之前的传参:
Expanded(flex: 1, child: textField()),
修改完成后点击列表项给_selectedField赋值的逻辑就能正常生效了,TextEditingController本身是可监听对象,赋值text属性后会自动通知绑定的输入框更新,不需要把赋值逻辑放在setState内部也能正常运行。
内容的提问来源于stack exchange,提问作者Omatt
相关产品推荐
相关产品推荐

