Flutter中实现单按钮表格计算功能的优化方案
问题描述
产品数据表格截图:包含两行产品数据,列依次为Products、Load(Qty)、Bal(Qty)、Amount,初始Amount值均为0。
现有两行产品数据,包含产品名称、Load(qty)、Balance(qty)、Amount列,需按照公式Amount = (load - balance)*2计算每行的Amount值并显示在对应行的Amount字段中。要求仅通过一个名为calculate的按钮实现计算,且避免使用示例中重复定义的变量。
原代码
class MyHomePage extends Stateful Widget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final loadCntrlr1 = TextEditingController(); final loadCntrlr2 = TextEditingController(); final balCntrlr1 = TextEditingController(); final balCntrlr2 = TextEditingController(); final amount1 = 0; final amount2 = 0; @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ FittedBox( child: DataTable(columns: const [ DataColumn( label: Text('Products'), ), DataColumn( label: Text('Load(Qty)'), ), DataColumn( label: Text('Bal(Qty)'), ), DataColumn( label: Text('Amount'), ), ], rows: [ DataRow(cells: [ const DataCell( Text('Furniture'), ), DataCell( TextFormField( keyboardType: TextInputType.number, controller: loadCntrlr1, ), ), DataCell( TextFormField( keyboardType: TextInputType.number, controller: balCntrlr1, ), ), const DataCell( Text('0'), ), ]), DataRow(cells: [ const DataCell( Text('Dhall'), ), DataCell( TextFormField( keyboardType: TextInputType.number, controller: loadCntrlr2, ), ), DataCell( TextFormField( keyboardType: TextInputType.number, controller: balCntrlr2, ), ), const DataCell( Text('0'), ), ]), ]), ), ElevatedButton(onPressed: () {}, child: Text('calculate')) ], ), ), ); } }
优化实现代码
class MyHomePage extends Stateful Widget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } // 封装单个产品的所有数据 class Product { final String name; final TextEditingController loadController; final TextEditingController balanceController; int amount; Product({ required this.name, required this.loadController, required this.balanceController, this.amount = 0, }); } class _MyHomePageState extends State<MyHomePage> { // 用列表统一管理所有产品,避免重复定义变量 final List<Product> products = [ Product( name: 'Furniture', loadController: TextEditingController(), balanceController: TextEditingController(), ), Product( name: 'Dhall', loadController: TextEditingController(), balanceController: TextEditingController(), ), ]; // 批量计算所有产品的Amount值 void calculateAmounts() { setState(() { for (var product in products) { // 解析输入值,处理空输入或非数字的情况 final load = int.tryParse(product.loadController.text) ?? 0; final balance = int.tryParse(product.balanceController.text) ?? 0; product.amount = (load - balance) * 2; } }); } @override void dispose() { // 统一释放所有控制器资源,防止内存泄漏 for (var product in products) { product.loadController.dispose(); product.balanceController.dispose(); } super.dispose(); } @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ FittedBox( child: DataTable( columns: const [ DataColumn(label: Text('Products')), DataColumn(label: Text('Load(Qty)')), DataColumn(label: Text('Bal(Qty)')), DataColumn(label: Text('Amount')), ], // 根据产品列表动态生成表格行,减少重复代码 rows: products.map((product) { return DataRow(cells: [ DataCell(Text(product.name)), DataCell( TextFormField( keyboardType: TextInputType.number, controller: product.loadController, ), ), DataCell( TextFormField( keyboardType: TextInputType.number, controller: product.balanceController, ), ), DataCell(Text(product.amount.toString())), ]); }).toList(), ), ), ElevatedButton( onPressed: calculateAmounts, child: const Text('calculate'), ) ], ), ), ); } }
核心改进说明
- 用
Product类封装每个产品的名称、输入控制器和计算结果,避免重复定义多个独立变量 - 通过列表统一管理所有产品数据,便于遍历计算和UI生成
- 动态生成DataTable的行,消除重复的UI代码
- 在计算方法中统一处理所有产品的逻辑,点击按钮后通过
setState更新UI显示计算结果 - 统一释放所有控制器资源,避免内存泄漏
内容的提问来源于stack exchange,提问作者Afthal Ad
相关产品推荐
相关产品推荐

