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
menuMapto map eachFilterModevalue to its correspondingMenuItem - See if we have a
RosterViewState, and if we do, mark theMenuItemfor the currentFilterModeas 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.