Home > Enterprise >  Programmatically added submenu items are not selected after navigation
Programmatically added submenu items are not selected after navigation

Time:01-13

I have the following main menu drawer, where the "Home button" is static, but the elements under "Read groups" are dynamically added. As you can see, the Home menu is properly checked (selected).

Menu printscreen

The groups all navigate to the same fragment (GroupsShowFragment), but with different parameters. The problem is, that if I navigate to such a group, the menu item selection is not updated (the Home selection even stays active).

Below the drawer_menu.xml code:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view"
    >

    <group android:checkableBehavior="single">
        <item
            android:id="@ id/menu_nav_home"
            android:icon="@drawable/ic_action_home"
            android:title="Home" />

    </group>

    <group android:checkableBehavior="single" android:id="@ id/groups_sub_holder">
        <item
            android:id="@ id/groups_holder"
            android:title="Read groups">
            <menu>
            </menu>
        </item>
    </group>

    <item android:title="Controls">
        <menu>
            <group android:checkableBehavior="single">
                <item
                    android:id="@ id/menu_nav_group_add"
                    android:icon="@drawable/ic_action_add_group"
                    android:title="@string/fragment_title_groups_add" />
                <item
                    android:id="@ id/menu_nav_settings"
                    android:icon="@drawable/ic_action_settings"
                    android:title="Settings" />
            </group>
        </menu>
    </item>

</menu>

The code used to dynamicly add the read groups (data is coming from a Room database):

// Add menu source: https://stackoverflow.com/a/31722855/1175881
val navigationView: NavigationView = findViewById <NavigationView> (R.id.nav_view)
val menu: Menu = (navigationView.menu.findItem(R.id.groups_holder)).subMenu
menu.clear()

// adding a section and items into it
val allGroups:  List<Groups> = GroupsManager.getAllGroups()
allGroups.forEach{
    it.uid?.let { it1 -> menu.add(0, it1, 0, it.name) }
}

And the code which is handling the "navigation":

private fun handleNavigateTrigger(menuId: Int){
    when(menuId) {
        R.id.menu_nav_home -> {
            homeFragment = HomeFragment()
            showFragment(homeFragment)
        }
        R.id.menu_nav_settings -> {
            settingsFragment = SettingsFragment()
            showFragment(settingsFragment)
        }
        R.id.menu_nav_group_add -> {
            groupsAddFragment = GroupsAddFragment()
            showFragment(groupsAddFragment)
        }
        else -> {
            groupsShowFragment = GroupsShowFragment.newInstance(menuId)
            showFragment(groupsShowFragment)

            val navigationView: NavigationView = findViewById <NavigationView> (R.id.nav_view)
            Log.e("handleNavigateTrigger", "setCheckedItem($menuId)")
            navigationView.setCheckedItem(menuId)
        }
    }
    _drawerLayout.closeDrawer(GravityCompat.START)
}

private fun showFragment(fragment:  androidx.fragment.app.Fragment){
    supportFragmentManager
        .beginTransaction()
        .replace(R.id.frame_layout, fragment)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
        .commit()
}

The log does show the correct id's (at least the correct integers) used, so I'm a bit lost here. I've added the group with android:checkableBehavior="single" like this, even as whole menu parent, but to no avail. I'm feeling like I miss one small but very important step, but can't find what that is..

CodePudding user response:

This is a self-answer, but wanted to share the found solution for anybody in the future (can only accept this answer in 2 days, so I'll get back to do that)

I've finally stumbled on this SO answer by Danial B.

Using only the setChecked resulted in a partial (but not sufficient and correctly working) checked menu item. I had to make sure that the menu item was checkable with setCheckable. This resulted in the following code for me:

val navigationView: NavigationView = findViewById <NavigationView> (R.id.nav_view)
val groupItem: MenuItem = navigationView.menu.findItem(menuId)
groupItem.isCheckable = true
groupItem.isChecked = true
  • Related