Как обновить значение LiveData?

Я использую новую библиотеку подкачки для своих данных. Все работает нормально, когда ViewModel создается и сначала инициализируются данные в реальном времени. Проблема в том, что я не могу обновить значение моих данных в реальном времени, когда, например, я нажимаю пункт меню и хочу обновить его другим набором данных. Тогда метод onChanged в моем фрагменте не вызывается. Я читал о MutableLiveData и таких методах, как setValue и postValue, которые могут обновлять данные в реальном времени, но в моем случае я использую LivePagedListProvider и не могу вернуть MutableLiveData из базы данных.

Дао:

@Query("SELECT * FROM teams ORDER BY name ASC")
LivePagedListProvider<Integer, Team> getAllTeams();

Фрагмент:

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;
    }
}

person tomas    schedule 16.11.2017    source источник
comment
Аннотированный метод @Update поможет (или Вставить или Удалить)   -  person pskink    schedule 16.11.2017
comment
Вы хотите обновить, вставить или удалить что-то в моей таблице, чтобы это сработало на onChanged? Это может сработать, но что мне обновить?   -  person tomas    schedule 16.11.2017
comment
вам следует обновить запись, которую вы хотите изменить, но для учебных целей просто вставьте новую запись - это намного проще   -  person pskink    schedule 16.11.2017
comment
хорошо, но я не хочу ничего менять в своей таблице, я просто хочу получить другой набор данных, как в моем примере, получить только любимые команды, а затем обновить свой адаптер с их помощью   -  person tomas    schedule 16.11.2017


Ответы (3)


Наконец я нашел решение после трех дней борьбы,

Для обновления значения LiveData<PagedList> мы можем использовать MediatorLiveData, как показано ниже, внутри вашего ViewModel класса:

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;
}

Дополнительную информацию о MediatorLiveData можно найти здесь

person Anushka Khare    schedule 08.05.2018
comment
Вы пробовали DataSource.Factory в сочетании с MediatorLiveData? У вас получилось? - person Roar Grønmo; 11.01.2019

Создайте isFavourite столбец в своей модели. Потом:

@Query("SELECT * FROM teams WHERE isFavourite = true")
LivePagedListProvider<Integer, Team> getFavouriteTeams();

Затем у вас должен быть ViewModel с функцией / полем, возвращающим MutableLiveData<PagedList<Team>> и в _5 _ / _ 6_, которое вы наблюдаете за этим полем. В вашем _7 _ / _ 8_ вы сообщаете ViewModel каждое изменение, которое вам нужно сделать, чтобы отображался список. Затем в ViewModel вы назначаете различные значения списку оперативных данных.

person Damia Fuentes    schedule 16.11.2017
comment
Но я не хочу показывать только два списка. Фактически, у меня есть 5 различных вариантов отображения списка по категориям. Поэтому я считаю, что создавать переходник для каждого из них - не лучший вариант. Вместо этого у меня работают разные наблюдатели, но один адаптер. Также работает удаление и установка одного наблюдателя каждый раз, когда я нажимаю на одну из своих категорий. Как вы думаете, такой подход хорош? - person tomas; 17.11.2017

Transformations.switchMap может помочь: 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)
}

Если вы хотите изменить процесс поиска на поиск по идентификатору команды (или переключиться на другой источник данных), просто позвоните из фрагмента:

viewModel.changeTeamId(2)
person jno    schedule 01.04.2019