Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set shared checkable behavior across all groups in NavigationView?

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.

like image 401
EyesClear Avatar asked Jun 10 '15 20:06

EyesClear


2 Answers

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.

like image 152
EyesClear Avatar answered Oct 10 '22 13:10

EyesClear


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)

Menu with dividers

<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());     ... } 
like image 28
Till Avatar answered Oct 10 '22 13:10

Till