使用GetX与GetBuilder时TextFormField值无法更新的问题
问题原因
你遇到的问题是TextFormField的initialValue仅在组件首次构建时生效,后续即使通过update()触发GetBuilder重新渲染,输入框也不会读取新的initialValue,因此内容无法更新。而Row里的Text组件会在每次数据变化时重新渲染,所以能正常显示最新值。
解决方案
为每个动态生成的TextFormField绑定TextEditingController,通过控制器直接控制输入框的文本内容,这样批量赋值时只需更新控制器的text属性,就能同步刷新输入框内容。
1. 修改GetX控制器
添加控制器列表维护每个输入框的TextEditingController,并在批量赋值时同步更新控制器内容:
import 'dart:convert'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; class LabourBulkController extends GetxController { List workersList = []; List<TextEditingController> amountControllers = []; // 新增:存储每个输入框的控制器 bool loading = false; getActiveLabours() async { loading = true; update(); // 先更新加载状态 SharedPreferences prefs = await SharedPreferences.getInstance(); var token = prefs.getString("token"); var response = await http.get( Uri.parse("xxxxxxxxxxxxxxxxxxxxxxx"), headers: {'Authorization': 'Bearer $token'}); var data = jsonDecode(response.body); workersList.clear(); amountControllers.clear(); // 清空旧控制器 for (var i = 0; i < data['data'].length; i++) { Map customerData = { "id": data['data'][i]['worker_id'], "name": data['data'][i]['worker_name'], "amount": 0, }; workersList.add(customerData); amountControllers.add(TextEditingController(text: '0')); // 初始化控制器 } loading = false; update(); } assignAtOnce(String amount) { for (var i = 0; i < workersList.length; i++) { workersList[i]['amount'] = amount; amountControllers[i].text = amount; // 同步更新控制器文本 } update(); } // 新增:页面销毁时释放控制器资源 void disposeControllers() { amountControllers.forEach((controller) => controller.dispose()); } }
2. 修改Widget代码中的TextFormField
替换initialValue为控制器绑定:
GetBuilder<LabourBulkController>(builder: (dx) { return ListView.builder( itemCount: dx.workersList.length, physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (BuildContext context, int index) { return Card( child: Padding( padding: const EdgeInsets.all(8.0), child: Column(children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ const SizedBox(width: 10, height: 50), const Icon(FeatherIcons.user), const SizedBox(width: 20), Text( "${dx.workersList[index]['name']} | ${dx.workersList[index]['amount'].toString()}", style: const TextStyle(fontSize: 18), ), ], ), TextFormField( keyboardType: TextInputType.number, decoration: const InputDecoration( border: OutlineInputBorder(), hintText: "Wages", prefixIcon: Icon(Icons.wallet, color: Colors.blue)), controller: dx.amountControllers[index], // 使用控制器绑定 onChanged: (value) { dx.workersList[index]['amount'] = value; dx.update(); // 同步更新其他组件(如上方的Text) }, ) ]), ), ); }); }),
3. 页面销毁时释放资源
在页面的State类中添加dispose方法,释放控制器资源避免内存泄漏:
@override void dispose() { _bulkController.disposeControllers(); super.dispose(); }
效果说明
修改后,当你在AlertDialog的输入框中输入内容时,assignAtOnce方法会同时更新workersList数据和所有输入框控制器的文本,GetBuilder触发渲染后,所有TextFormField会同步显示最新的批量赋值内容,Row里的Text也会继续正常更新。
内容的提问来源于stack exchange,提问作者swapnil mane
相关产品推荐
相关产品推荐

