tomas
tomas

Reputation: 416

How to update LiveData value?

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

Answers (3)

Anushka Khare
Anushka Khare

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

jno
jno

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

Damia Fuentes
Damia Fuentes

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

Related Questions