Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android support:design NavigationView checked menu sub items

I have recently started converting my android app to use the latest support library called support:design.

While implementing the new NavigationView i've stumbled upon a problem displaying the selected menu items.

My navdrawer_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/navigation_item_home"
        android:icon="@drawable/ic_home_black"
        android:title="@string/navdrawer_item_home" />
</group>

    <item
        android:id="@+id/navigation_subheader"
        android:title="@string/navdrawer_subheader_title1">
        <menu>
            <group android:checkableBehavior="single">
            <item
                android:id="@+id/navigation_sub_item1"
                android:icon="@drawable/ic_home_black"
                android:title="@string/navdrawer_sub_item1" />
            </group>
        </menu>
    </item>
</menu>

Next I set the menu's item to checked in my onNavigationItemSelected:

@Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {

    menuItem.setChecked(true);

    drawerLayout.closeDrawer(GravityCompat.START);
    mDrawerActionHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            displayView(menuItem.getItemId());
        }
    }, DRAWER_CLOSE_DELAY_MS);
    return true;
}

This works great if I only use normal menu items between the tags but it does not work very well for subheaders. Clicking on sub items wont set them checked untill i've clicked the same item twice and it won't uncheck the any item that checked previously.

It ends up looking like this:

enter image description here

like image 586
John Van den Berg Avatar asked Jun 11 '15 11:06

John Van den Berg


2 Answers

Every item must be inside a group, so the group can control the item's visual behavor on user select. Try it:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/navigation_item_home"
        android:icon="@drawable/ic_home_black"
        android:title="@string/navdrawer_item_home" />
    <item
        android:id="@+id/navigation_subheader"
        android:title="@string/navdrawer_subheader_title1">
        <menu>
            <group android:checkableBehavior="single">
            <item
                android:id="@+id/navigation_sub_item1"
                android:icon="@drawable/ic_home_black"
                android:title="@string/navdrawer_sub_item1" />
            </group>
        </menu>
    </item>
</group>
</menu>
like image 129
Michel Fortes Avatar answered Oct 18 '22 02:10

Michel Fortes


I resolved this recurrent problem in this way that works very well.

We must simply memorize the id of the selected item, recharge your menu on your NavigationView and select the item again.

For that you need to have your menu drawer like way :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/section_1"
        android:title="@string/section_title">

        <menu>
            <group android:checkableBehavior="single">
                <item
                    android:id="@+id/item_1_section_1"
                    android:icon="@drawable/ic_icon"
                    android:title="@string/title"/>

                <item
                    android:id="@+id/item_2_section_1"
                    android:icon="@drawable/ic_icon"
                    android:title="@string/title"/>
                ...
            </group>
        </menu>
    </item>
        ...
    <item
        android:id="@+id/section_x"
        android:title="@string/section_title">

        <menu>
            <group android:checkableBehavior="single">
                <item
                    android:id="@+id/item_1_section_x"
                    android:icon="@drawable/ic_icon"
                    android:title="@string/title"/>

                <item
                    android:id="@+id/item_2_section_x"
                    android:icon="@drawable/ic_icon"
                    android:title="@string/title"/>
                ...
            </group>
        </menu>
    </item>
</menu>

So, my solution :

public class YourActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

...
private NavigationView mNavigationView;
private int mNavItemId;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    // load saved navigation state if present
    if (null == savedInstanceState) {
        mNavItemId = R.id.item_1_section_1;
    } else {
        mNavItemId = savedInstanceState.getInt(NAV_ITEM_ID);
    }

    // listen for navigation events
    mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
    mNavigationView.setNavigationItemSelectedListener(this);

    // select the correct nav menu item
    mNavigationView.getMenu().findItem(mNavItemId).setChecked(true);
}

@Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
    // update highlighted item in the navigation menu
    mNavItemId = menuItem.getItemId();

    // allow some time after closing the drawer before performing real navigation
    // so the user can see what is happening
    mDrawerLayout.closeDrawer(GravityCompat.START);
    mDrawerActionHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            ...
        }
    }, DRAWER_CLOSE_DELAY_MS);

    // Reload menuDrawer to keep selected item
    mNavigationView.getMenu().clear();
    mNavigationView.inflateMenu(R.menu.menu_drawer);
    mNavigationView.getMenu().findItem(mNavItemId).setChecked(true);

    return true;
}

...

}
like image 3
lopez.mikhael Avatar answered Oct 18 '22 03:10

lopez.mikhael