所以我来自MVP背景......我基本上要做的就是在我们开始从Room(SQLite)获取数据时启动loadingView,在成功时停止loadingView并且所有逻辑应该是在我的ViewModel(试图保持我的片段干净)处理Fragment的类。
我现在所做的是我有两个LiveData:
这就是我的意思:
enum HomeState{
LOADING,
LIVE
}
private LiveData<List<SomeData>> someData;
private MutableLiveData<HomeState> homeState;
我正在我的片段中观察两者并且我希望让我的homeStateLiveData确定片段是否应该显示加载视图。正如您可能看到的,这将无法正常工作,因为新数据出现时它会立即转到片段我无法从ViewModel控制homeState逻辑
正如您可能看到的那样,这将不起作用,因为当新数据出现时,它立即进入片段,我无法从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。体系结构组件指南有关于如何执行此操作的an example(相关类型),它们监视网络的状态,但您可以轻松地将其适应您的数据库方案。