android - 使用 Room Livedata MVVM 时如何显示 LoadingState
问题描述
所以我来自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。架构组件指南有一个关于如何执行此操作的示例(有点相关),它们在那里监视网络的状态,但您可以轻松地将其适应您的数据库场景。
推荐阅读
- c# - Azure WebJobs SDK 和模拟器 - 触发器不起作用
- c# - 从非常大的 int 数组 c# 初始化特定索引
- assembly - 寄存器间接模式的 x86 机器码格式
- reactjs - localhost http 500 内部服务器错误条带反应
- python-3.6 - cursor.fetchall() 抛出索引或范围错误
- c - 我不能将指针声明为全局变量
- codenameone - 从屏幕支持时转到特定选项卡
- android - 无法通过 adb shell 创建日志文件
- c# - 在门户编辑器中更新 csproj 文件 Azure 函数
- html - 添加了 UWP applicationcontenturirules url 规则,但不适用于 iframe