I am working on a screen that shows the contents of a Room wrapped DB using a recycler. The adapter gets the LiveData from a ViewModel that hides the query call on the Room DAO object. So, the LiveData object is actually a ComputableLiveData object that is aware of changes to the Room DB.
Now I want to add filter options to the screen. Where / how would I implement this in this Room-LiveData-ViewModel setup?
Should the adapter or ViewModel "postfilter" the results in the LiveData? Should I requery the data from room for every filter change? Can I reuse the underlying (Computable)LiveData for that? If not, should I really create new LiveData for every filter change?
A similar question is discussed here: Reload RecyclerView after data change with Room, ViewModel and LiveData
I'm working in a similar problem. Initially I had RxJava but now I'm converting it to LiveData.
This is how I'm doing inside my ViewModel:
// Inside ViewModel
MutableLiveData<FilterState> modelFilter = new MutableLiveData<>();
LiveData<PagedList<Model>> modelLiveData;
This modelLivedata is constructed in the following way inside view model constructor:
// In ViewModel constructor
modelLiveData = Transformations.switchMap(modelFilter,
new android.arch.core.util.Function<FilterState, LiveData<PagedList<Model>>>() {
@Override
public LiveData<PagedList<Model>> apply(FilterState filterState) {
return modelRepository.getModelLiveData(getQueryFromFilter(filterState));
}
});
When the view model receives another filter to be applied, it does:
// In ViewModel. This method receives the filtering data and sets the modelFilter
// mutablelivedata with this new filter. This will be "transformed" in new modelLiveData value.
public void filterModel(FilterState filterState) {
modelFilter.postValue(filterState);
}
Then, this new filter will be "transformed" in a new livedata value which will be sent to the observer (a fragment).
The fragment gets the livedata to observe through a call in the view model:
// In ViewModel
public LiveData<PagedList<Model>> getModelLiveData() {
return modelLiveData;
}
And inside my fragment I have:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ViewModel viewModel = ViewModelProviders.of(this.getActivity()).get(ViewModel.class);
viewModel.getModelLiveData().observe(this.getViewLifecycleOwner(), new Observer<PagedList<Model>>() {
@Override
public void onChanged(@Nullable PagedList<Model> model) {
modelListViewAdapter.submitList(model);
}
});
}
I hope it helps.