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:
- We cannot easily access a menu item at an arbitrary point in time, so we need to hold onto the menu items when we set up the menu
- We need to be able to get the right menu item for the current
FilterMode
- We need to handle this work both when the menu is created and when the state gets updated, as there is no guaranteed order of when those two things happen
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:
- Populate the
menuMap
to map eachFilterMode
value to its correspondingMenuItem
- See if we have a
RosterViewState
, and if we do, mark theMenuItem
for the currentFilterMode
as checked
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.