我是LiveData的新手,最近我一直在做一些测试。我有一个应用程序,需要显示可以过滤的数据(名称,类别,日期...)。过滤器也可以组合(名称+日期)。此数据来自Retrofit + RXJava的API调用。
我知道无需使用LiveData,就可以直接在视图上保存数据。但是,我认为使用ViewModel + LiveData会很有趣。首先,要测试它的工作方式,还要避免在视图处于非活动状态时尝试设置数据(感谢LiveData),并在配置发生更改时保存数据(感谢ViewModel)。这些是我之前必须手动处理的事情。
所以问题是我没有找到一种使用LiveData轻松处理筛选器的方法。在用户选择一个过滤器的情况下,我设法使其与switchMap一起使用:
return Transformations.switchMap(filter,
filter -> LiveDataReactiveStreams.fromPublisher(
repository.getData(filter).toFlowable(BackpressureStrategy.BUFFER)));
[如果他选择两个过滤器,我看到我可以使用自定义的MediatorLiveData,这就是我所做的。但是,这里的问题是我的存储库调用完成了与过滤器数量相同的次数和我不能同时设置两个过滤器。
我的自定义MediatorLiveData:
class CustomLiveData extends MediatorLiveData<Filter> {
CustomLiveData(LiveData<String> name, LiveData<String> category) {
addSource(name, name -> {
setValue(new Filter(name, category.getValue()));
});
addSource(category, category -> {
setValue(new Filter(name.getValue(), newCategory));
});
}
}
CustomLiveData trigger = new CustomLiveData(name, category);
return Transformations.switchMap(trigger,
filter -> LiveDataReactiveStreams.fromPublisher(
repository.getData(filter.getName(), filter.getCategory())
.toFlowable(BackpressureStrategy.BUFFER)));
我是否了解MediatorLiveData的用法?是否可以使用LiveData来实现我想要的目标?
谢谢!
我认为我从错误的角度看问题。如果我错了,请纠正我。
当我可以直接更新LiveData时,我试图根据其他LiveData的更改来更新LiveData。我发现的解决方案是拥有一个MediatorLiveData,该视图直接由视图更新。它可能是MutableLiveData,但是由于我正在使用LiveDataReactiveStreams,并且它不接受MutableLiveData,所以我没有找到其他解决方案。
public class MainViewModel extends AndroidViewModel {
// Had to use a MediatorLiveData because the LiveDataReactiveStreams does not accept a MutableLiveData
private MediatorLiveData<List<Data>> data = new MediatorLiveData<>();
public MainViewModel(@NonNull Application application) {
super(application);
data.addSource(
LiveDataReactiveStreams.fromPublisher(
repository.getData(name, category)
.toFlowable(BackpressureStrategy.BUFFER)
), value -> data.setValue(value));
}
public LiveData<List<Data>> getData() {
return data;
}
public void updateData(String name, String category) {
data.addSource(
LiveDataReactiveStreams.fromPublisher(
repository.getData(name, category)
.toFlowable(BackpressureStrategy.BUFFER)
), value -> data.setValue(value));
}
}
然后在活动中,我只是这样称呼它:
viewModel.updateMoviesList(page, category);
我不知道在尝试添加另一个源之前是否应该删除一个源,但是使用此解决方案,我的API调用只能执行一次,并且我可以同时拥有两个过滤器。