我试图观察特定表中的数据,方法是使用Flowable<List<T>>
获取元素,使用库LiveDataStreams
将其转换为LiveData
,然后观察最后一个观察必须从单击按钮开始。当我的用户第一次点击按钮时,它会从服务器下载数据,将其保存到相应的表中,然后设置观察者。当我再次单击按钮时,问题变成了,因为它下载数据并将其保存到表中,但它不会从Observer
调用onChanged
方法。
在代码中,ParentFragment的onViewCreated
方法在其中调用showItemsList
,因为其他子片段必须这样做,但就目前的情况而言,我必须在按钮的onclick之后开始观察列表。
ParentFragment:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mNavController = Navigation.findNavController(getDataBindingObject().getRoot());
showItemsList();
}
protected void showItemsList() {
mViewModel.getList().observe(getViewLifecycleOwner(), listObserver);
}
protected final Observer<List<T>> listObserver = new Observer<List<T>>() {
@Override
public void onChanged(List<T> list) {
getAct().getSupportActionBar().setTitle(getString(mViewModel.getTitleId(), list.size()));
mViewModel.setListAdapter(list);
}
};
ChildFragment(当前案例):
@Override
protected void showItemsList() {
mDataBinding.searchButton.setOnClickListener(v -> {
mViewModel.download()
.subscribe(downloaded -> super.showItemsList()
, t -> DialogUtils.showMessage(R.string.error_binding_data));
});
}
ViewModel:
public LiveData<List<T>> getList() {
if (list == null) {
LiveData<List<T>> lD = LiveDataReactiveStreams.fromPublisher(mRepository.getList());
list = new MediatorLiveData<>();
list.addSource(lD, l -> {
list.setValue(l);
list.remove(lD);
});
}
return list;
}
存储库:
public Flowable<List<T>> getList() {
if (list == null) list = dao.getItems();
return list;
}
刀:
public abstract Flowable<List<MyItem>> getItems();
您在负责从Flowable
转换为LiveData
的代码中犯了一个错误。
在第一次调用getList()
时,您将创建一个观察Flowable
的LiveData
对象,但在检索第一个项目后,您将停止观察Flowable
。稍后将此LiveData
分配给字段。
在getList()
的第二次调用中,您将获得分配给字段(没有源)的LiveData
对象,因此不会通知片段中的观察者。
你可以像这个一样修改你的代码
public LiveData<List<T>> getList() {
if (list == null) {
LiveData<List<T>> lD = LiveDataReactiveStreams.fromPublisher(mRepository.getList());
list = new MediatorLiveData<>();
list.addSource(lD, l -> {
list.setValue(l);
});
}
return list;
}