Reputation: 416
I am using the new paging library for my data. Everything works fine when the ViewModel is created and live data is first initialized. Problem is that I can not update the value of my live data when for example I click on menu Item and want to update it with a different set of data. Then onChanged method in my fragment does not get called. I have read about MutableLiveData and methods like setValue and postValue which can update the live data, but in my case, I am using LivePagedListProvider and cannot return MutableLiveData from a database.
Dao:
@Query("SELECT * FROM teams ORDER BY name ASC")
LivePagedListProvider<Integer, Team> getAllTeams();
Fragment:
mTeamViewModel.mTeamsList.observe(this, new Observer<PagedList<Team>>() {
@Override
public void onChanged(@Nullable PagedList<Team> teams) {
mTeamAdapter.setList(teams);
}
});
ViewModel:
public LiveData<PagedList<Team>> mTeamsList;
@Inject
DatabaseManager mDatabaseManager;
void setTeamViewModel(final DatabaseManager databaseManager) {
mDatabaseManager = databaseManager;
mTeamsList = mDatabaseManager.getAllTeams().create(
0,
new PagedList.Config.Builder()
.setPageSize(50)
.setPrefetchDistance(50)
.setEnablePlaceholders(true)
.build());
}
boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorite:
mTeamsList = mDatabaseManager.getFavoriteTeams().create(
0,
new PagedList.Config.Builder()
.setPageSize(50)
.setPrefetchDistance(50)
.build());
return true;
default: return false;
}
}
Upvotes: 6
Views: 17106
Reputation: 363
Finally I found the solution after the struggle of 3 days,
For updating the value of LiveData<PagedList>
we can use MediatorLiveData
, as follows, inside your ViewModel
class:
public LiveData<PagedList<RecipeListPojo>> liveData;
private MediatorLiveData<PagedList<RecipeListPojo>> mediatorLiveData;
public RecipeListViewModel(@NonNull Application application) {
super(application);
mediatorLiveData = new MediatorLiveData<>();
}
public MediatorLiveData<PagedList<RecipeListPojo>> init(RecipeDao recipeDao, RecipeFrom recipeFrom, String orderBy) {
liveData = new LivePagedListBuilder(recipeDao.getAllRecipesList(simpleSQLiteQuery), 6).build();
mediatorLiveData.addSource(liveData, new Observer<PagedList<RecipeListPojo>>() {
@Override
public void onChanged(@Nullable PagedList<RecipeListPojo> recipeListPojos) {
mediatorLiveData.setValue(recipeListPojos);
}
});
return mediatorLiveData;
}
Further details can be found here about MediatorLiveData
Upvotes: 10
Reputation: 31
Transformations.switchMap can help: https://developer.android.com/reference/android/arch/lifecycle/Transformations#switchmap
class SearchViewModel() : ViewModel(){
val teamId = MutableLiveData<Int>()
var teamsList: LiveData<PagedList<Team>>=
Transformations.switchMap(teamId) { id ->
//just example
if (id <= 0) {
//1
searchDbManager.searchWithoutId()
} else {
//2
anotherSearchDbManager.searchWithId(id)
}.setBoundaryCallback(SearchResultBoundaryCallback()).build()
}
}
fun changeTeamId(id : Int){
teamId.postValue(id)
}
If you want to change the search process to search with team ID (or switch to another datasource), just call from Fragment:
viewModel.changeTeamId(2)
Upvotes: 1
Reputation: 5503
Create a isFavourite
column in your model. Then:
@Query("SELECT * FROM teams WHERE isFavourite = true")
LivePagedListProvider<Integer, Team> getFavouriteTeams();
Then you should have a ViewModel
with a function/field that returns a MutableLiveData<PagedList<Team>>
and in the Fragment
/Activity
you observe to that field. In your Fragment
/Activity
you tell the ViewModel
every change you need to do to de list showed. Then in the ViewModel
you assign different values to the live data list.
Upvotes: 2