如何手动触发ViewModel的LiveData Observer第二次回调以跨Fragment更新RecyclerView
实现方案
不需要手动调用已注册Observer的onChange方法,利用LiveData的原生观察者机制即可实现自动触发,核心是保证两个Fragment观察的是同一个LiveData实例,最推荐的官方方案是通过共享Activity作用域的ViewModel完成同步,具体步骤如下:
- 第一步:两个Fragment获取ViewModel时绑定宿主Activity的生命周期,保证拿到同一个ViewModel实例
如果之前你初始化ViewModel时传入的是Fragment自身实例,两个Fragment会拿到独立的ViewModel实例,无法实现数据同步,统一修改初始化代码为:
保持第一个Fragment原有LiveData观察代码不变即可。// 注意此处传入requireActivity()而非Fragment自身,生成的是全局唯一的Activity级ViewModel ItemViewModel item_viewmodel = new ViewModelProvider(requireActivity()).get(ItemViewModel.class); - 第二步:第二个Fragment完成数据修改后,直接更新对应LiveData的值
如果你是本地维护列表数据,修改后直接给LiveData设置新值:
如果你的// 第二个Fragment中修改完数据后执行,主线程用setValue,子线程用postValue List<Items> updatedList = 修改后生成的新列表数据; item_viewmodel.getAllCategoryModel().setValue(updatedList);getAllCategoryModel()返回的是Room持久化库的查询LiveData,只需要在第二个Fragment中更新Room对应表的记录,Room会自动刷新LiveData的值,不需要手动赋值。 - 此时同一ViewModel下的同个LiveData实例发生数据变更,所有处于活跃状态的观察者(包含第一个Fragment已经注册的Observer)都会自动触发
onChanged回调,完成第一个Fragment的列表更新。
可选替代方案
如果不想共享ViewModel,也可以使用官方Fragment Result API实现跨Fragment通信:第二个Fragment修改完成后发送结果通知,第一个Fragment监听结果事件,收到通知后主动拉取最新数据刷新列表即可,不过该方案耦合度高于共享ViewModel方案,优先推荐前者。
内容的提问来源于stack exchange,提问作者Rivke
相关产品推荐
相关产品推荐

