I have 3 same fragments in a ViewPager that each contain a ViewModel where I observe for changes on the fragment whenever the list is changed.
Here's the observer;
mReleasesViewModel = ViewModelProviders.of(this, new ReleasesViewModelFactory(filter)).get(ReleasesViewModel.class);
// livedata
mDatabaseLoading.setVisibility(View.VISIBLE);
mReleasesViewModel.getUpcomingReleases().observe(this, new Observer<List<_Release>>() {
@Override
public void onChanged(@Nullable List<_Release> releases) {
// whenever the list is changed
if (releases != null) {
mUpcomingGamesAdapter.setData(releases);
mUpcomingGamesAdapter.notifyDataSetChanged();
}
mDatabaseLoading.setVisibility(View.GONE);
}
});
Now in the MainActivity there's a drawer that contains platforms to filter from e.g PC, Xbox and PS4, and when the user closes the drawer I want all of my 3 fragments to update gracefully, is this possible to accomplish with viewmodel? Like how can I observer for list changes and for platforms changes? The drawer in Main Activity adds the selected platforms to a list of Integer e.g PS4 has id of 3
My ViewModel:
public class ReleasesViewModel extends ViewModel {
public static final String TAG = ViewModel.class.getSimpleName();
// Example: Whenever the value contained by this MutableLiveData changes, we will set the contained value to our TextView
// Livedata objects will usually be kept in the ViewModel class
private MutableLiveData<List<_Release>> upcomingReleases;
// this field [mMonthYearFilter] is passed by our fragment to the AndroidViewModel
// to pass additional argument to my custom AndroidViewModel I need a AndroidViewModelFactory
private String monthYearFilter;
private ReleasesRepository releasesRepository;
public ReleasesViewModel(String monthYearFilter) {
this.monthYearFilter = monthYearFilter;
}
public MutableLiveData<List<_Release>> getUpcomingReleases() {
if (upcomingReleases == null) {
upcomingReleases = new MutableLiveData<>();
// User settings region & platforms
String region = SharedPrefManager.read(SharedPrefManager.KEY_PREF_REGION, "North America");
Set<String> defaultPlatformsSet = new HashSet<>();
ArrayList<Integer> platforms = SharedPrefManager.read(SharedPrefManager.PLATFORM_IDS, defaultPlatformsSet);
releasesRepository = new ReleasesRepository(region, monthYearFilter, platforms);
loadReleases();
}
return upcomingReleases;
}
private void loadReleases() {
releasesRepository.addListener(new FirebaseDatabaseRepository.FirebaseDatabaseRepositoryCallback<_Release>() {
@Override
public void onSuccess(List<_Release> result) {
upcomingReleases.setValue(result);
}
@Override
public void onError(Exception e) {
Log.e(TAG, e.getMessage());
upcomingReleases.setValue(null);
}
});
}
}
Have only 1 ViewModel
created at an Activity level and pass it to your fragments. Your ViewModel
can have 3 LiveData
serving for each of your fragments. let's assume you are showing upcoming releases in one fragment and already released games in another. So just like you did for upcoming releases, create another method in your ViewModel
and return a LiveData
which will hold the list of released games.
In the below code mViewModel
will be the passed view model to your fragments.
mViewModel.getReleasedGames().observe(this, new Observer<List<_Release>>() {
@Override
public void onChanged(@Nullable List<_Release> released_games) {
// whenever the list is changed
if (released_games != null) {
mReleasedGamesAdapter.setData(releases);
mReleasedGamesAdapter.notifyDataSetChanged();
}
mDatabaseLoading.setVisibility(View.GONE);
}
});