You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在数据库更新后立即刷新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可以实现自动刷新:

  1. 让数据库查询方法返回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();
  });
}
  1. 在表格页面用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为例)

如果项目规模较大,用状态管理库可以更好地分离业务逻辑:

  1. 创建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();
  }
}
  1. 在表格页面通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:28:13