Flutter ObjectBox使用Data Observers & Rx监听实体变更列表不刷新如何解决
Flutter ObjectBox 监听实体字段变更实现页面列表同步方案
原有代码不生效的核心原因
StreamSubscription订阅对象被GC回收:如果sub1是方法内的局部变量,方法执行完成后实例会被系统回收,后续无法收到回调,必须将其定义为页面State类的成员变量。- 变更未同步到数据库:如果仅修改了内存中
InvoiceList实例的dispatch属性,没有调用box.put()方法将变更持久化到数据库,ObjectBox感知不到数据变更,不会触发监听回调。 - 旧版本兼容问题:1.4.0以下版本的ObjectBox存在
watch()方法触发异常的已知问题,需升级到最新稳定版。
正确实现代码
class DeliveryListPage extends StatefulWidget { const DeliveryListPage({super.key}); @override State<DeliveryListPage> createState() => _DeliveryListPageState(); } class _DeliveryListPageState extends State<DeliveryListPage> { // 订阅对象定义为类成员变量,避免被GC回收 late StreamSubscription<Query<InvoiceList>> sub1; // 页面展示的列表数据 List<InvoiceList> deliveryList = []; @override void initState() { super.initState(); // 1. 构建查询条件,生成Query实例 final Query<InvoiceList> query = deliveryListBox! .query(InvoiceList_.dispatch.equals(true)) .build(); // 2. 开启监听,triggerImmediately设为true会首次加载时主动触发回调拿到初始数据 final Stream<Query<InvoiceList>> watchedQuery = query.watch(triggerImmediately: true); // 3. 订阅数据变更回调 sub1 = watchedQuery.listen((Query<InvoiceList> latestQuery) { // 直接通过回调返回的query实例拿到最新数据,无需额外重复查询数据库 setState(() { deliveryList = latestQuery.find(); }); }); } @override void dispose() { // 页面销毁时取消订阅,避免内存泄漏 sub1.cancel(); super.dispose(); } @override Widget build(BuildContext context) { // 直接使用deliveryList渲染列表即可 return ListView.builder( itemCount: deliveryList.length, itemBuilder: (context, index) => ListTile(title: Text(deliveryList[index].orderNo)), ); } }
可选优化:仅监听dispatch字段变更
如果需要忽略InvoiceList其他字段的变更,只在dispatch字段修改时才触发列表更新,可通过distinct方法对流做过滤:
final Stream<Query<InvoiceList>> watchedQuery = query.watch(triggerImmediately: true) .distinct((prevQuery, nextQuery) { final prevList = prevQuery.find(); final nextList = nextQuery.find(); // 列表长度变化直接判定为变更 if (prevList.length != nextList.length) return false; // 逐行对比dispatch字段,只要有一个发生变更就触发更新 for (int i = 0; i < prevList.length; i++) { if (prevList[i].dispatch != nextList[i].dispatch) return false; } // 所有数据的dispatch字段无变化,不触发回调 return true; });
内容的提问来源于stack exchange,提问作者Pratik Butani
相关产品推荐
相关产品推荐

