LiveData观察者与onPrepareOptionsMenu竞争问题

5

我正在开发一个项目,该项目允许用户以访客或注册用户的身份登录。有一个应用程序范围的user对象,其中包含当前用户类型的LiveData。

private val _isGuest = MutableLiveData<Boolean>()
val isGuest: LiveData<Boolean>
    get() = _isGuest

有一个 HomeFragment,需要为已注册用户显示 logout 菜单项。该片段具有绑定到全局属性的 ViewModel。

val isGuest: LiveData<Boolean> = MainApplication.user.isGuest

该片段观察数据

var menu: Menu? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    ...
    viewModel.isGuest.observe(viewLifecycleOwner, Observer {
        menu?.findItem(R.id.action_logout)?.isVisible = !it
    })
}

override fun onPrepareOptionsMenu(menu: Menu) {
    this.menu = menu
    menu.findItem(R.id.action_logout)?.isVisible = !isGuest
    super.onPrepareOptionsMenu(menu)
}

因为注册用户可以在运行时注销,当前屏幕需要相应更新,所以我需要在观察者中切换菜单项。

问题在于,我还必须在onPrepareOptionsMenu中复制代码,因为观察者可能会在启动时在菜单初始化之前被通知。当然,我可以将那行代码移动到一个单独的函数中,并从两个点调用它,但难道没有更好的解决方案吗?

1个回答

2
使用invalidateOptionsMenu()来触发onPrepareOptionMenu()。
var menu: Menu? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...
viewModel.isGuest.observe(viewLifecycleOwner, Observer {
            activity?.invalidateOptionsMenu()//This will trigger onPrepareOptionsMenu
})
}

override fun onPrepareOptionsMenu(menu: Menu) {
this.menu = menu
menu.findItem(R.id.action_logout)?.isVisible = !isGuest
super.onPrepareOptionsMenu(menu)
}

当观察者被通知时,菜单可能尚不存在。 - yaugenka
所以你想在菜单准备好后观察实时数据的变化,你可以调用以下代码: viewModel.isGuest.observe(viewLifecycleOwner, Observer { activity?.invalidateOptionsMenu()//这将触发onPrepareOptionsMenu方法 }) 在super.onPrepareOptionsMenu(menu)之后。 - Roshan Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接