如何在Flutter DataTable的多DataRow场景下管理TextField控制器
实现方案
你当前的问题是所有行的TextField共用了同一个全局控制器,导致输入值无法和对应商品绑定,按以下步骤修改即可:
步骤1:为每个商品单独配置控制器
推荐直接在你的商品模型类中新增控制器属性,无需额外维护映射关系:
// 你的商品Model类新增属性 class Product { // 原有属性:name, pTR, balQty等 late TextEditingController qtyController; }
在你获取到listOfProduct商品列表数据后,遍历为每个商品初始化控制器:
// 示例:拿到接口/本地返回的商品列表后执行 listOfProduct = await getProductList(); for (var product in listOfProduct!) { product.qtyController = TextEditingController(); // 如需设置默认数量,可加下行代码 // product.qtyController.text = product.defaultQty.toString(); }
步骤2:修改TextField的控制器绑定
替换原来全局共用的控制器,改用当前行商品自带的控制器:
DataCell( TextField( controller: element.qtyController, // 替换为当前商品的控制器 maxLength: 4, decoration: InputDecoration( labelText: 'Qty', labelStyle: TextStyle(fontSize: 9.sp), counterText: "", ), // 可选:设置键盘为数字输入 keyboardType: TextInputType.number, ), )
步骤3:获取所有商品对应的输入值
点击Add按钮时,直接遍历商品列表即可拿到每个商品对应输入的数量:
OutlinedButton( onPressed: () async { listOfProduct!.forEach((product) { String inputText = product.qtyController.text.trim(); int? inputQty = int.tryParse(inputText); // 可自行添加校验逻辑,比如非数字/空值默认转为0 inputQty ??= 0; print("商品:${product.name},输入数量:$inputQty"); // 赋值给商品的数量字段即可完成绑定 // product.inputQty = inputQty; }); // 后续业务逻辑 }, child: const Text("Add"), )
步骤4:释放控制器避免内存泄漏
在当前页面的State的dispose生命周期中,批量释放所有控制器:
@override void dispose() { for (var product in listOfProduct!) { product.qtyController.dispose(); } super.dispose(); }
替代方案(无需修改Model类)
如果你不想改动原有商品模型,可以在当前页面维护一个控制器映射表:
// 页面内定义,key为商品唯一标识(比如商品ID) Map<int, TextEditingController> qtyControllerMap = {}; // 初始化商品列表时生成控制器 listOfProduct = await getProductList(); for (var product in listOfProduct!) { qtyControllerMap[product.id] = TextEditingController(); } // TextField绑定时使用 controller: qtyControllerMap[element.id]! // 释放时遍历映射表销毁 @override void dispose() { qtyControllerMap.values.forEach((controller) => controller.dispose()); super.dispose(); }
内容的提问来源于stack exchange,提问作者Kalp Shah
相关产品推荐
相关产品推荐

