Cómo establecer el comportamiento de comprobación compartida en todos los grupos en NavigationView?

He creado dos grupos con identificadores únicos (necesito un divisor) y ambos tienen checkableBehavior configurado como single . Esto permite que varios elementos de diferentes grupos se verifiquen a la vez, y eso es exactamente lo que estoy tratando de evitar. Me gustaría tener un elemento marcado al máximo, en todos los grupos.

Como no he encontrado ninguna forma de hacerlo en XML, intenté implementar una lógica simple en onNavigationItemSelected para desmarcar el elemento de menú anterior:

 if (previousItem != null) previousItem.setChecked(false); currentItem.setChecked(true); 

Pero el setChecked(false) nunca ha funcionado para mí – el elemento permanece marcado.

Aquí está mi código de ejemplo:

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; } }); 

¡Necesito una pista! Gracias.

Aquí está la solución.

Paso 1: Eliminar

 android:checkableBehavior="single" 

De ambos grupos.

Paso 2: Agregue la siguiente lógica al oyente:

 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; } }); 

Nota: en lugar de llamar a menuItem.setCheckable(true) puedes establecer android:checkable="true" para cada elemento en XML.

@ La solución de Moinkhan debe funcionar también (gracias, upvoted), pero no quería hacer bucle a través de los elementos del menú cada vez que se selecciona una nueva posición.

En realidad, no es necesario separar grupos paralelos para separadores. Puedes tener todo en un grupo y colocar submenús (tener títulos) o subgrupos (sin título) en él. Habrá separadores para esos submenús y subgrupos. De esta manera el comportamiento comprobable funciona sin una solución. (Fyi: Esto está en el Libro de Apoyo de Diseño 23.1.1)

Menú con separadores

 <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> 

En código, simplemente hago las siguientes y una sola comprobación funciona como se esperaba:

 @Override public boolean onNavigationItemSelected(MenuItem item) { mNavigationView.setCheckedItem(item.getItemId()); ... } 

No es necesario eliminar checkableBehavior="single" , solo usa

 navigationView.setCheckedItem(item.getItemId()); 

En lugar de item.setChecked(true) .

Ok encontré la solución .. solo agrega este código de fragmento al método onNavigationItemSelected

 @Override public boolean onNavigationItemSelected(MenuItem menuItem) { Menu m = navView.getMenu(); for (int i=0;i<m.size();i++) { MenuItem mi = m.getItem(i); if (!(mi.getItemId() == menuItem.getItemId())) { mi.setCheckable(false); } } menuItem.setCheckable(true); menuItem.setChecked(true); return false; } 

Eso es todo .. Y sí setChecked (falso) no funciona. Sólo porque de la lista de menú debe haber un solo elemento debe ser cheked. Así que sólo puede desmarcarlo cuando seleccione otro elemento. Y si hace clic en el elemento seleccionado, la vista de navegación nunca lo desmarcará. Sólo porque el escenario que he explicado.

Parece que hay un error de invalidación en la implementación de NavigationView , pero no es necesario usar setCheckable() , sólo tiene que invalidar NavigationView después de llamar a setChecked(false) , así:

  previousItem.setChecked(false); navigationView.invalidate(); 

Sin embargo, el grupo de menús no debe tener checkableBehavior="single" , ya que en modo exclusivo llamando setChecked(boolean) en un MenuItem del grupo configurará ese elemento como verificado si pasa true o false. Así que para que setChecked(false) funcione, debes quitar checkableBehavior="single" de las definiciones de tu menú.

He creado un problema sobre esto aquí: https://code.google.com/p/android/issues/detail?id=178709

Aquí está una solución simple y dulce que posteé aquí 🙂

Hacer grupos diferentes hace un divisor entre los dos pero crea el problema de dos elementos marcados en el cajón de nav.

Una manera simple cómo manejé esto era:

  public boolean onNavigationItemSelected(final MenuItem menuItem) { //if an item from extras group is clicked,refresh NAV_ITEMS_MAIN to remove previously checked item if (menuItem.getGroupId() == NAV_ITEMS_EXTRA) { navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, false, true); navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, true, true); }else{ navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, true, true); navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, false, true); } //Update highlighted item in the navigation menu menuItem.setChecked(true); 

}

  • Cómo agregar un elemento a un grupo de menús en NavigationView
  • Actividades o Fragmentos en NavigationView?
  • ¿Cómo diseñar el NavigationView de la biblioteca de soporte de diseño?
  • NavigationView selecciona el elemento seleccionado como
  • Cómo dar color de texto personalizado para un solo elemento de menú en un NavigationView?
  • Error de lanzamiento de NavigationView: No se encontró ningún identificador de recurso para el atributo 'menu' en el paquete
  • NavigationView cómo manejar contenido de encabezado dinámico
  • Uso de NavigationView desde Android Design Support Library
  • Cómo agregar vistas personalizadas en el nuevo NavigationView
  • ClassNotFoundException: No encontró la clase "android.support.design.R $ styleable"
  • Obtención de error al inflar la clase android.support.design.widget.NavigationView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.