架构组件刷新LiveData

时间:2018-04-18 19:05:45

标签: android android-livedata android-viewmodel android-architecture-components

我正在努力使用架构组件在主 - 详细视图上刷新数据的正确方法。我有一个单顶主要活动,显示最喜欢的电影列表。当我转到详细信息视图时,从收藏夹添加/删除电影并关闭详细信息视图主视图的数据保持不同步。我在onCreate方法中初始化视图模型:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
   moviesViewModel = ViewModelProviders
                    .of(this, viewModelFactory)
                    .get(MoviesViewModel.class);
   moviesViewModel.getMovies(FAVOURITES).observe(this, this::show);
}

View Model也很简单:

@NonNull
LiveData<Resource<List<Movie>>> getMovies(Criterion criterion) {
   movieRepository.fetchBy(criterion)
                .doOnSubscribe(it -> moviesLiveData.setValue(Resource.loading()))
                .subscribe(
                        movies -> moviesLiveData.setValue(Resource.success(movies)),
                        throwable -> moviesLiveData.setValue(Resource.error(throwable))
                );

最简单的解决方案是每次激活视图时强制刷新视图:

@Override
public void onResume() {
   super.onResume();
   moviesViewModel.getMovies(FAVOURITES).observe(this, this::show);
}

但我真的不喜欢这种方法,因为它会在屏幕方向改变时以及活动来自背景时产生刷新。

也可以仅在结果发生时启动结果和刷新数据的细节活动,但我也不认为这是在反应式方法中应该如何以这种方式完成的。

此外,我正在考虑订阅强大的解析器中的数据库更改,并在每次数据更改时使用新内容更新Flowable,但我确信它是否会起作用,因为更改发生时实时数据观察者(主视图) )处于暂停模式,因此不会被通知,我是对的吗?

2 个答案:

答案 0 :(得分:1)

有几种方法可以管理刷新主视图。

  1. 您可以在这种情况下使用共享的ViewModel。如果主视图和局部视图都是片段,则您所要做的就是使用相同的视图模型,将活动或包含的片段作为范围传入,例如ViewModelProviders.of(parentFragment!!, viewModelFactory)。然后您的moviesLiveData可以同时在母版页和详细页上看到。 **请注意,最新版的Navigation通过将ViewModel绑定到特定的导航图,使您可以更精确地定义范围。
  2. 如果您在页面上使用活动,则可以通过详细信息屏幕中的startActivityForResultsetResult将电影结果信息传递回主页,并在{{1}中检索信息。 }
  3. 您可以将网络请求的结果缓存在除ViewModel之外的其他地方。通常,您可能有一个Singleton存储库来检索您的数据。您可以按照与ViewModels相同的模式使用onActivityResult
  4. 您还可以按照建议观察数据库。不用担心它处于暂停模式!这就是LiveData的意义,它存储了最新的更新,并在有人发现时再次提供。

答案 1 :(得分:0)

您还可以将livedata用于数据库,以便从db-> vm-> ui更新更改