当视图模型中更新另一个 LiveData 时触发 LiveData 成员的更新

Trigger update for a LiveData member when another LiveData is updated in the view model

在文字游戏应用程序中,我在 activity 和片段之间共享一个模型:

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

(请原谅截图中的非英文文字)

activity 观察用户当前正在播放 mGames 并更新导航抽屉菜单(请参见上面屏幕截图的左侧)。

片段观察mDisplayedGame并将其显示在自定义视图中(见上图右侧)。

我的问题是当游戏列表在服务器上更新时(并且 activity 通过 Websocket 接收新的游戏列表并将其存储在房间),我需要 post 更新片段:"Hey, the game you are displaying was updated, redraw it!"

是否可以从共享视图模型中执行此操作?

我知道我也可以在片段中观察 mGames 并在那里添加一个代码来遍历它们,然后查明显示的游戏是否在服务器上更新了。

但我更愿意在 MainViewModel 中这样做,因为我觉得片段应该只观察它正在显示的一个游戏,仅此而已。

TL;DR

每当通过 Room 在视图模型中更新 mGames 时,我也需要通知 mDisplayedGame 观察者!

使用回调兄弟 - 在您的视图模型中添加一个回调接口和一个 setCallback 方法 -让你的片段实现它然后调用 viewmodel.setCallback(片段) -在你的观察者中调用回调

您应该为此使用 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>,它应该可以正常工作。