Flutter中TextFormField设置controller文本后无法编辑的问题
问题原因及解决方案
你的问题根源在于把控制器文本赋值操作放在了build方法中。Flutter的build方法会在Widget状态变更、父组件重建等场景下频繁执行,每次执行都会重新设置itemNameController.text的值,直接覆盖用户输入的内容,导致文本框看起来处于“静态不可编辑”的状态。
正确的实现方式
1. 初始化时设置固定初始值
如果数据库数据是在页面初始化时就能获取到的同步数据,直接在initState方法中设置控制器文本:
class _AddItemFromImageState extends State<AddItemFromImage> { TextEditingController itemNameController = TextEditingController(); TextEditingController itemPriceController = TextEditingController(); TextEditingController itemDiscountController = TextEditingController(); TextEditingController totalItemCountController = TextEditingController(); @override void initState() { super.initState(); // 在这里设置初始值,只会执行一次 itemNameController.text = "Viyasan Dev Muthusamy"; // 替换为你的数据库同步取值逻辑 // itemPriceController.text = [数据库加载的同步价格值]; } @override void dispose() { itemNameController.dispose(); itemPriceController.dispose(); itemDiscountController.dispose(); totalItemCountController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { // 移除build方法内的控制器赋值代码 return Scaffold( resizeToAvoidBottomInset: false, appBar: !widget.isImageInput ? AppBar( title: Text( "SampleCode Test", style: TextStyle( fontWeight: FontWeight.bold, ), ), ) : null, body: Container( child: Column( children: [ SizedBox(height: 40.0), Padding( padding: EdgeInsets.all(6.0), child: Text( AppStringHolder.lblMsgImgItem, textAlign: TextAlign.center, ), ), SizedBox(height: 40.0), Padding( padding: EdgeInsets.all(10.0), child: TextFormField( onTap: () {}, controller: itemNameController, keyboardType: TextInputType.text, onChanged: (value) => onChangedItemName(value), decoration: _commonInputStyle(Colors.blueGrey, Colors.blueGrey, AppStringHolder.lblItemName, false), ), ), SizedBox(height: 60.0), ], ), ), ); } }
2. 异步加载数据库数据
如果数据库数据是异步获取的(比如网络请求、本地SQLite查询),在initState中启动异步任务,获取数据后更新控制器:
@override void initState() { super.initState(); _loadDataFromDatabase(); } Future<void> _loadDataFromDatabase() async { // 模拟异步获取数据库数据的逻辑 String itemName = await fetchItemNameFromDB(); String itemPrice = await fetchItemPriceFromDB(); // 直接更新控制器文本,无需调用setState(控制器内部会通知UI更新) itemNameController.text = itemName; itemPriceController.text = itemPrice; }
关键注意事项
- 永远不要在
build方法中做状态修改、数据赋值操作,build仅负责根据当前状态构建UI。 - TextEditingController的
text属性可直接修改,无需调用setState,控制器内部会自动触发UI更新。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

