首页 > 解决方案 > 使用 Room Livedata MVVM 时如何显示 LoadingState

问题描述

所以我来自MVP背景......我基本上想做的是在我们开始从Room(SQLite)获取数据后立即启动loadingView,成功时停止loadingView,所有这些逻辑都应该是在我的ViewModel(试图保持我的片段干净)类中处理 Fragment。

我现在所做的是我有两个 LiveData:

  1. 我来自数据库的实际数据
  2. 片段状态的实时数据:

这就是我的意思:

enum HomeState{
    LOADING,
    LIVE
}    
private LiveData<List<SomeData>> someData;
private MutableLiveData<HomeState> homeState;

我在我的片段中观察,我想让我的 homeStateLiveData 确定片段是否应该显示加载视图。你可能会看到,这不起作用,因为当新数据到来时它会立即进入片段而且我无法从 ViewModel 控制 homeState 逻辑

标签: androidandroid-architecture-componentsandroid-livedataandroid-mvvm

解决方案


正如您可能看到的那样,这不起作用,因为当新数据到来时,它会立即进入片段,我无法从 ViewModel 控制 homeState 逻辑

您可以通过将自己置于片段的观察者和数据库的 LiveData 之间来控制基于数据库 LiveData 的 homeState。您可以通过转换或 MediatorLiveData 执行此操作。

// with a Transformation
// this would be the method which returns the database LiveData
public LiveData<List<SomeData>> getDatabaseData() {
     // the view should show a loading indicator
     homeState.setValue(HomeState.LOADING);
     // we don't actually map anything, we just use the map function to get 
     // a callback of when the database's LiveData has finished loading  
     return Transformations.map(dao.getSomeData(), list -> {
         // the database has just finished fetching the data from the database
         // and after this method returns it will be available to the observer
         // in the fragment.
         // we also need to dismiss the loading indicator
         homeState.setValue(HomeState.LIVE);
         return list;
     });
}

使用 MediatorLiveData 您可以执行类似的操作,只需让 MediatorLiveData 侦听数据库 LiveData 并在添加数据库 LiveData 作为其源时在它设置的观察者中更新 homeState。

如果您想对此进行抽象,您可以将从数据库中获取的数据和状态(正在加载或可用)包装到单个类中,并将 ViewModel 更改为仅返回带有该类的 LiveData。架构组件指南有一个关于如何执行此操作的示例(有点相关),它们在那里监视网络的状态,但您可以轻松地将其适应您的数据库场景。


推荐阅读