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

Flutter中无需使用FutureBuilder,能否监听Hive数据库的数据变化?

解决Flutter Hive单例结合Provider实现自动数据监听(无需FutureBuilder)

核心思路

把Hive单例助手类改造为ChangeNotifier子类,在每次修改Hive数据后调用notifyListeners()触发UI刷新;同时在应用启动时完成Hive初始化,通过Provider全局注入助手类实例,UI层通过Consumer或Provider.of监听数据变化。


1. 改造Hive单例助手类

保留单例模式的同时继承ChangeNotifier,在增删改数据的方法中添加通知逻辑:

import 'package:hive/hive.dart';
import 'package:flutter/foundation.dart';

// 示例数据模型类
part 'your_model.g.dart';

@HiveType(typeId: 0)
class YourModel extends HiveObject {
  @HiveField(0)
  final String id;
  @HiveField(1)
  final String content;

  YourModel({required this.id, required this.content});
}

class HiveHelper extends ChangeNotifier {
  static final HiveHelper _instance = HiveHelper._internal();
  late Box<YourModel> _box;

  factory HiveHelper() => _instance;

  HiveHelper._internal() {
    // 这里依赖main函数中提前打开的box
    _box = Hive.box<YourModel>('your_data_box');
  }

  // 获取数据列表
  List<YourModel> get dataList => _box.values.toList();

  // 添加数据后通知UI刷新
  void addItem(YourModel item) {
    _box.add(item);
    notifyListeners();
  }

  // 删除数据后通知UI刷新
  void deleteItem(int index) {
    _box.deleteAt(index);
    notifyListeners();
  }

  // 修改数据后通知UI刷新
  void updateItem(int index, YourModel newItem) {
    _box.putAt(index, newItem);
    notifyListeners();
  }
}

2. 应用启动时完成Hive初始化

在main函数中先完成Hive初始化、适配器注册、box打开,再启动应用,避免使用FutureBuilder:

import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化Hive
  await Hive.initFlutter();
  
  // 注册数据模型适配器(需提前运行build_runner生成)
  Hive.registerAdapter(YourModelAdapter());
  
  // 打开目标box
  await Hive.openBox<YourModel>('your_data_box');

  runApp(
    ChangeNotifierProvider(
      create: (context) => HiveHelper(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hive + Provider Demo',
      home: const DataListPage(),
    );
  }
}

3. UI层监听数据变化

使用Consumer组件监听HiveHelper的变化,自动刷新UI:

class DataListPage extends StatelessWidget {
  const DataListPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('数据列表')),
      body: Consumer<HiveHelper>(
        builder: (context, hiveHelper, child) {
          final data = hiveHelper.dataList;
          if (data.isEmpty) {
            return const Center(child: Text('暂无数据'));
          }
          return ListView.builder(
            itemCount: data.length,
            itemBuilder: (context, index) {
              final item = data[index];
              return ListTile(
                title: Text(item.content),
                trailing: IconButton(
                  icon: const Icon(Icons.delete),
                  onPressed: () => hiveHelper.deleteItem(index),
                ),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 添加测试数据
          final newItem = YourModel(
            id: DateTime.now().millisecondsSinceEpoch.toString(),
            content: '新数据 ${DateTime.now().minute}:${DateTime.now().second}',
          );
          // 无需监听变化,所以listen设为false
          Provider.of<HiveHelper>(context, listen: false).addItem(newItem);
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

关键注意事项

  • 运行flutter packages pub run build_runner build生成Hive模型的适配器代码,否则无法正常序列化数据。
  • 确保在main函数中完成Hive的所有初始化操作(init、注册适配器、打开box),避免UI层出现未初始化错误。
  • 在按钮点击等无需监听变化的场景中,使用Provider.of<HiveHelper>(context, listen: false)避免不必要的UI重建。

内容的提问来源于stack exchange,提问作者Kyaw Gyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:45:45