如何为Flutter中含code等字段的可编辑表格创建数据模型
Flutter 可编辑表格数据模型实现与关联方案
1. 定义数据模型类
先写对应字段的数据模型,为适配Flutter状态更新逻辑,加上copyWith方法生成新对象(避免直接修改字段导致UI不刷新):
class TableItem { String code; String codename; double price; double kilograms; TableItem({ required this.code, required this.codename, required this.price, required this.kilograms, }); // 用于单字段更新的copyWith方法 TableItem copyWith({ String? code, String? codename, double? price, double? kilograms, }) { return TableItem( code: code ?? this.code, codename: codename ?? this.codename, price: price ?? this.price, kilograms: kilograms ?? this.kilograms, ); } }
2. 实现可编辑表格的状态管理
用StatefulWidget维护表格数据列表,通过setState更新数据并同步UI:
class EditableTableScreen extends StatefulWidget { const EditableTableScreen({super.key}); @override State<EditableTableScreen> createState() => _EditableTableScreenState(); } class _EditableTableScreenState extends State<EditableTableScreen> { // 初始化测试数据 final List<TableItem> _tableData = [ TableItem(code: '001', codename: '苹果', price: 5.99, kilograms: 2.5), TableItem(code: '002', codename: '香蕉', price: 3.49, kilograms: 1.8), ]; // 更新指定索引的表格数据 void _updateItem(int index, TableItem updatedItem) { setState(() { _tableData[index] = updatedItem; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('可编辑表格')), body: SingleChildScrollView( child: DataTable( columns: const [ DataColumn(label: Text('编码')), DataColumn(label: Text('名称')), DataColumn(label: Text('单价')), DataColumn(label: Text('重量')), ], // 将数据列表转为表格行 rows: _tableData.asMap().entries.map((entry) { final index = entry.key; final item = entry.value; return DataRow(cells: [ // 编码输入框 DataCell( TextField( controller: TextEditingController(text: item.code), onChanged: (value) => _updateItem(index, item.copyWith(code: value)), ), ), // 名称输入框 DataCell( TextField( controller: TextEditingController(text: item.codename), onChanged: (value) => _updateItem(index, item.copyWith(codename: value)), ), ), // 单价输入框(处理数字输入) DataCell( TextField( controller: TextEditingController(text: item.price.toString()), keyboardType: TextInputType.numberWithOptions(decimal: true), onChanged: (value) { final newPrice = double.tryParse(value) ?? item.price; _updateItem(index, item.copyWith(price: newPrice)); }, ), ), // 重量输入框(处理数字输入) DataCell( TextField( controller: TextEditingController(text: item.kilograms.toString()), keyboardType: TextInputType.numberWithOptions(decimal: true), onChanged: (value) { final newKg = double.tryParse(value) ?? item.kilograms; _updateItem(index, item.copyWith(kilograms: newKg)); }, ), ), ]); }).toList(), ), ), ); } }
关键注意点
- 用
asMap()获取数据索引,确保准确找到要更新的行 - 编辑时通过
copyWith生成新的TableItem对象,保证setState能触发UI刷新 - 数字输入加异常处理,避免非数字输入导致崩溃
- 若数据量较大或需跨页面共享,可替换为
Provider、Riverpod等状态管理库,核心逻辑不变
内容的提问来源于stack exchange,提问作者Abdulla Alkurdy
相关产品推荐
相关产品推荐

