使用 Room Livedata MVVM 时如何显示 LoadingState
How to show LoadingState when using Room Livedata MVVM
所以我来自 MVP 背景...
我基本上想做的是在我们开始从 Room (SQLite) 获取数据时启动一个 loadingView,在成功时停止 loadingView,所有这些逻辑都应该在我的 ViewModel[=23 中处理=](试图保持我的片段干净)class 为片段。
我现在所做的是我有两个 LiveData:
- 我来自数据库的实际数据
- 片段状态的实时数据:
我的意思是:
enum HomeState{
LOADING,
LIVE
}
private LiveData<List<SomeData>> someData;
private MutableLiveData<HomeState> homeState;
我正在观察我的片段,我想让我的 homeStateLiveData 确定片段是否应该显示加载视图。正如您可能看到的那样,当新数据出现时,这将不起作用立即转到片段,我无法从 ViewModel
控制 homeState 逻辑
我在 mvvm
、rx
、kotlin
、retorfit
中为 recyclerview
使用加载状态。
Here是我的实际加载状态
Here 是我用于观察加载状态的绑定适配器。
Here 是我扩展的 recyclerview
class 用于加载状态和空视图。
Here 是我的 xml 绑定加载状态文件。
也许你可以从我的例子中得到启发。
As you can probably see, this won't work as when the new data comes it
immediately goes to the fragment and I can't control the homeState
logic from the ViewModel
您可以通过将自己置于片段的观察者和数据库的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。
如果你想对此进行抽象,你可以将从数据库中获取的数据和状态(正在加载或可用)包装成一个 class 并将你的 ViewModel 更改为仅 return class 的 LiveData。体系结构组件指南an example(有点相关)介绍了如何执行此操作,它们在那里监视网络状态,但您可以轻松地使其适应您的数据库方案。
所以我来自 MVP 背景... 我基本上想做的是在我们开始从 Room (SQLite) 获取数据时启动一个 loadingView,在成功时停止 loadingView,所有这些逻辑都应该在我的 ViewModel[=23 中处理=](试图保持我的片段干净)class 为片段。
我现在所做的是我有两个 LiveData:
- 我来自数据库的实际数据
- 片段状态的实时数据:
我的意思是:
enum HomeState{
LOADING,
LIVE
}
private LiveData<List<SomeData>> someData;
private MutableLiveData<HomeState> homeState;
我正在观察我的片段,我想让我的 homeStateLiveData 确定片段是否应该显示加载视图。正如您可能看到的那样,当新数据出现时,这将不起作用立即转到片段,我无法从 ViewModel
控制 homeState 逻辑我在 mvvm
、rx
、kotlin
、retorfit
中为 recyclerview
使用加载状态。
Here是我的实际加载状态
Here 是我用于观察加载状态的绑定适配器。
Here 是我扩展的 recyclerview
class 用于加载状态和空视图。
Here 是我的 xml 绑定加载状态文件。
也许你可以从我的例子中得到启发。
As you can probably see, this won't work as when the new data comes it immediately goes to the fragment and I can't control the homeState logic from the ViewModel
您可以通过将自己置于片段的观察者和数据库的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。
如果你想对此进行抽象,你可以将从数据库中获取的数据和状态(正在加载或可用)包装成一个 class 并将你的 ViewModel 更改为仅 return class 的 LiveData。体系结构组件指南an example(有点相关)介绍了如何执行此操作,它们在那里监视网络状态,但您可以轻松地使其适应您的数据库方案。