如何在数据库更新后立即刷新Flutter中的销售记录表格UI?
实现Flutter销售数据表格自动刷新的几种实用方案
方案一:StatefulWidget配合手动刷新
如果项目还没引入状态管理库,这是最直接的实现方式:
- 在表格页面的State类中维护销售数据列表,初始化时从数据库加载数据
- 弹窗表单提交成功后,重新查询数据库获取最新数据,调用
setState()更新列表
class SalesTablePageState extends State<SalesTablePage> { List<SalesRecord> _salesRecords = []; @override void initState() { super.initState(); _loadSalesData(); } // 从数据库加载销售数据 Future<void> _loadSalesData() async { final data = await DatabaseHelper.getSalesRecords(); setState(() { _salesRecords = data; }); } // 打开添加记录弹窗 void _showAddDialog() { showDialog( context: context, builder: (context) => AddSalesRecordDialog( onSubmit: (newRecord) async { // 提交新记录到数据库 await DatabaseHelper.insertSalesRecord(newRecord); Navigator.pop(context); // 刷新表格数据 _loadSalesData(); }, ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("销售数据")), body: DataTable( columns: const [ DataColumn(label: Text("日期")), DataColumn(label: Text("金额")), DataColumn(label: Text("客户")), ], rows: _salesRecords.map((record) => DataRow( cells: [ DataCell(Text(record.date)), DataCell(Text(record.amount.toString())), DataCell(Text(record.customerName)), ], )).toList(), ), floatingActionButton: FloatingActionButton( onPressed: _showAddDialog, child: const Icon(Icons.add), ), ); } }
方案二:StreamBuilder监听数据库实时变化
如果你的数据库支持返回数据流(比如sqflite的queryStream、Firebase Firestore的实时监听),用StreamBuilder可以实现自动刷新:
- 让数据库查询方法返回
Stream<List<SalesRecord>>:
// DatabaseHelper类中的方法 static Stream<List<SalesRecord>> getSalesStream() { // 以sqflite为例,监听sales表数据变化 return db.query('sales').map((rows) { return rows.map((row) => SalesRecord.fromMap(row)).toList(); }); }
- 在表格页面用StreamBuilder构建表格:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("销售数据")), body: StreamBuilder<List<SalesRecord>>( stream: DatabaseHelper.getSalesStream(), builder: (context, snapshot) { if (snapshot.hasData) { final records = snapshot.data!; return DataTable( columns: const [/* 列定义 */], rows: records.map((r) => DataRow(/* 单元格内容 */)).toList(), ); } else if (snapshot.hasError) { return Center(child: Text("加载失败: ${snapshot.error}")); } return const Center(child: CircularProgressIndicator()); }, ), floatingActionButton: FloatingActionButton( onPressed: _showAddDialog, child: const Icon(Icons.add), ), ); }
这种方式下,提交新记录后数据库会自动推送最新数据,表格无需手动调用刷新。
方案三:状态管理库(以Provider为例)
如果项目规模较大,用状态管理库可以更好地分离业务逻辑:
- 创建SalesProvider维护数据和业务方法:
class SalesProvider extends ChangeNotifier { List<SalesRecord> _records = []; List<SalesRecord> get records => _records; Future<void> loadData() async { _records = await DatabaseHelper.getSalesRecords(); notifyListeners(); } Future<void> addRecord(SalesRecord record) async { await DatabaseHelper.insertSalesRecord(record); // 添加后重新加载数据并通知页面刷新 await loadData(); } }
- 在表格页面通过Provider获取数据:
class SalesTablePage extends StatelessWidget { @override Widget build(BuildContext context) { final salesProvider = Provider.of<SalesProvider>(context); return Scaffold( appBar: AppBar(title: const Text("销售数据")), body: DataTable( columns: const [/* 列定义 */], rows: salesProvider.records.map((r) => DataRow(/* 单元格内容 */)).toList(), ), floatingActionButton: FloatingActionButton( onPressed: () { showDialog( context: context, builder: (context) => AddSalesRecordDialog( onSubmit: (newRecord) async { await salesProvider.addRecord(newRecord); Navigator.pop(context); }, ), ); }, child: const Icon(Icons.add), ), ); } }
记得在main函数中注册Provider:
void main() { runApp( ChangeNotifierProvider( create: (context) => SalesProvider()..loadData(), child: const MyApp(), ), ); }
内容的提问来源于stack exchange,提问作者Chirag Maurya
相关产品推荐
相关产品推荐

