Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LiveData observer vs onPrepareOptionsMenu race

I'm working on a project which lets users in either as guests or registerd users. There is an application scope user object with LiveData of the current user type

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

There is HomeFragment which needs to show logout menu item for registered users. The fragment has a ViewModel bound to the global property

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

and the fragment observes the data

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

I need to toggle the menu item in the observer because registered users can logout at runtime and the current screen will need to be updated respectively.

The problem is that I also have to duplicate the code in onPrepareOptionsMenu because the observer may get notified before menu is initilized at startup. Definitely I can move that line of code into a separate function and call it from the two points but aren't there a better solution?

like image 962
yaugenka Avatar asked Nov 07 '22 10:11

yaugenka


1 Answers

Use invalidateOptionsMenu() to trigger 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)
}
like image 96
Roshan Kumar Avatar answered Nov 17 '22 12:11

Roshan Kumar