Flutter中点击DropdownButton导致TextFormField恢复初始值如何解决
问题原因与解决方案
根因
你在TextFormField的controller属性中直接执行了_nameController..text = datumAdministrative.name赋值操作,这段代码写在build方法内,只要页面触发重绘就会被执行。当你展开DropdownButton时,键盘收起触发页面布局变化,进而触发整页重绘,此时输入框的内容就会被强制覆盖为初始的datumAdministrative.name,导致用户输入的新内容丢失。
解决方案
方案1(推荐,适合需要主动控制输入框内容的场景)
将Controller的初始赋值逻辑移到State的initState生命周期中,该方法仅会在State首次挂载到组件树时执行一次,不会每次重绘都重复赋值:
- 首先在State类中声明Controller:
late final TextEditingController _nameController;
- 在
initState中初始化并赋值初始值:
@override void initState() { super.initState(); // 初始化时赋值初始值,仅执行一次 _nameController = TextEditingController(text: datumAdministrative.name); }
- 修改TextFormField的controller配置,移除内嵌的赋值操作:
TextFormField( // 仅传入Controller,不要在这里赋值text controller: _nameController, // 其余原有配置保持不变 keyboardType: TextInputType.text, textCapitalization: TextCapitalization.sentences, onChanged: (value) => formValidator.name = value, validator: (value) { if (formValidator.fieldValidText(value)) { return null; } else { return Constants.nameAdministrativeMessage; } } )
- 记得在
dispose中销毁Controller避免内存泄漏:
@override void dispose() { _nameController.dispose(); super.dispose(); }
方案2(轻量场景适用)
如果不需要主动修改输入框内容,也可以直接使用initialValue属性配置初始值,无需自定义Controller:
TextFormField( // 直接配置初始值,不需要controller initialValue: datumAdministrative.name, // 其余原有配置保持不变 keyboardType: TextInputType.text, textCapitalization: TextCapitalization.sentences, onChanged: (value) => formValidator.name = value, validator: (value) { if (formValidator.fieldValidText(value)) { return null; } else { return Constants.nameAdministrativeMessage; } } )
注意:initialValue和controller不能同时使用,二选一即可。
内容的提问来源于stack exchange,提问作者Cesar Manuel
相关产品推荐
相关产品推荐

