I've created two groups with unique ids (I need a divider) and they both have checkableBehavior
set to single. This allows multiple items from different groups to be checked at once, and that's exactly what I'm trying to avoid. I'd like to have one item checked at maximum, across all groups.
Since I haven't found any way to do this in XML, I tried to implement a simple logic in onNavigationItemSelected
to uncheck the previous menu item:
if (previousItem != null) previousItem.setChecked(false); currentItem.setChecked(true);
but setChecked(false)
method has never worked for me - the item stays checked.
Here's my sample code:
menu_navigation.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:id="@+id/nav_group_1" android:checkableBehavior="single"> <item android:id="@+id/nav_feed" android:title="@string/feed"/> <item android:id="@+id/nav_people" android:title="@string/people"/> </group> <group android:id="@+id/nav_group_2" android:checkableBehavior="single"> <item android:id="@+id/nav_settings" android:title="@string/settings"/> <item android:id="@+id/nav_help_feedback" android:title="@string/help_feedback"/> <item android:id="@+id/nav_logout" android:title="@string/logout"/> </group>
NavigationItemSelectedListener:
mUiNavigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { if (previousItem != null) previousItem.setChecked(false); currentItem.setChecked(true); //... changeCurrentFragment(...); return true; } });
I need a hint! Thanks.
Here's the solution.
Step 1: Remove
android:checkableBehavior="single"
from both groups.
Step 2: Add the following logic to the listener:
mUiNavigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { menuItem.setCheckable(true); menuItem.setChecked(true); if (mPreviousMenuItem != null) { mPreviousMenuItem.setChecked(false); } mPreviousMenuItem = menuItem; //... changeCurrentFragment(...); return true; } });
Note: instead of calling menuItem.setCheckable(true)
you can set android:checkable="true"
for each item in XML.
@Moinkhan's solution should work as well (thanks, upvoted), but I didn't want to loop through menu's items each time a new position is selected.
Actually, you don't need separate parallel groups for separators. You can have everything in one group and place submenus (have titles) or subgroups (no title) in it. There will be separators for those submenus and subgroups. This way the checkable behavior works without a workaround. (Fyi: This is on Design Support Lib 23.1.1)
<group android:id="@+id/drawer_group" android:checkableBehavior="single"> <item android:id="@+id/nav_1" android:title="Menu1" /> <item android:id="@+id/nav_2" android:title="Menu2" /> <item android:id="@+id/nav_3" android:title="Menu3" /> <item android:id="@+id/nav_4" android:title="Menu4" /> <item android:id="@+id/drawer_submenu" android:title="Subheader"> <menu> <group android:checkableBehavior="single"> <item android:id="@+id/nav_sub1_1" android:title="Menu_Sub1_1" /> <item android:id="@+id/nav_sub1_2" android:title="Menu_Sub1_2" /> </group> </menu> </item> <group android:id="@+id/drawer_subgroup"> <item android:id="@+id/nav_subgroup_item" android:title="Menu_Sub2_2" /> </group> </group>
In code, I simply do the following and single checking works as expected:
@Override public boolean onNavigationItemSelected(MenuItem item) { mNavigationView.setCheckedItem(item.getItemId()); ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With