Запуск обновления для члена LiveData при обновлении другой LiveData в модели представления - PullRequest
0 голосов
/ 15 декабря 2018

В приложении для игры в слова я делю модель между действием и фрагментом:

public class MainViewModel extends AndroidViewModel {
    private LiveData<List<Game>> mGames;
    private final MutableLiveData<Game> mDisplayedGame = new MutableLiveData<>();

(прошу прощения за неанглийский текст на скриншоте)

activity and fragment

Задание наблюдает за тем, как пользователь в данный момент воспроизводит mGames, и обновляет меню навигационного ящика (см. Левую часть скриншота выше).

Фрагмент наблюдает mDisplayedGame и отображает его в пользовательском представлении (см. Правую часть приведенного выше снимка экрана).

Моя проблема заключается в том, что когдасписок игр обновляется на сервере (и действие получает новый список игр через Websocket и сохраняет его в комнате), мне нужно опубликовать обновление фрагмента: «Эй, игра, которую вы отображаете, была обновлена, перерисоватьэто! "

Возможно ли это сделать из модели общего представления?

Я знаю, что мог бы также наблюдать mGames во фрагменте и добавить туда код, проходящий через них изатем выяснить, отображается ли играобновляется на сервере.

Но я бы предпочел сделать это в MainViewModel, потому что у меня есть ощущение, что фрагмент должен наблюдать только за той игрой, которую он показывает, и все.

TL;DR

Всякий раз, когда mGames обновляется в модели вида через Room, я должен уведомить также mDisplayedGame наблюдателей!

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Вы должны использовать MediatorLiveData для этого.

Способ, которым это работает, заключается в том, что

public class MainViewModel extends AndroidViewModel {
    private final LiveData<List<Game>> mGames;
    private final MutableLiveData<Game> mSelectedGame = new MutableLiveData<>();

    private final MediatorLiveData<Game> mDisplayedGame = new MediatorLiveData<>();

    {
        mDisplayedGame.addSource(mGames, (data) -> {
            // find the new value of the selected game in the list
            mSelectedGame.setValue(newSelectedGame);
        });

        mDisplayedGame.addSource(mSelectedGame, (data) -> {
            mDisplayedGame.setValue(data);
        });
    }

А затем вы выставляете mDisplayedGame как LiveData<Game>, и он должен просто работать.

0 голосов
/ 15 декабря 2018

Используйте callback bro - добавьте интерфейс обратного вызова в вашей viewmodel и метод setCallback - сделайте так, чтобы ваш фрагмент реализовал его, затем вызовите viewmodel.setCallback (фрагмент) - вызовите обратный вызов в вашем наблюдателе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...