Step #8: Addressing the Menu Problem

We have one more glitch to fix.

If you filter the list, then click on a to-do item to view its details, then click BACK, you will find that the list is filtered, but the menu checked state is back to having the “All” option checked. That is because the UI of the RosterListFragment was rebuilt, and our menu reverted to its default state.

What we need to do is to have the menu reflect the current RosterViewState filterMode value. This is a bit annoying to implement:

To handle all of this, first add a menuMap property to RosterListFragment:

  private val menuMap = mutableMapOf<FilterMode, MenuItem>()

Then, modify the onCreateOptionsMenu() function in RosterListFragment to be:

  override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.actions_roster, menu)

    menuMap.apply {
      put(FilterMode.ALL, menu.findItem(R.id.all))
      put(FilterMode.COMPLETED, menu.findItem(R.id.completed))
      put(FilterMode.OUTSTANDING, menu.findItem(R.id.outstanding))
    }

    menuMap[motor.states.value.filterMode]?.isChecked = true

    super.onCreateOptionsMenu(menu, inflater)
  }

Here, we:

To find out the current value of the StateFlow, we can just reference value. That will either be the initial value or whatever the last emitted RosterViewState was.

Then, add this line to the bottom of the RosterViewState observer that we set up in onViewCreated():

        menuMap[state.filterMode]?.isChecked = true

This ensures that when we get a new RosterViewState that the appropriate MenuItem is checked.

Now, if you run the app, you should see that the filtering applied to the list matches the checked MenuItem, even after some navigation.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.