Je sais qu'il est possible de mettre en surbrillance un élément de vue de navigation en appelant setCheckedItem()
ou de renvoyer la valeur vraie dans onNavigationItemSelected
pour afficher l'élément en tant qu'élément sélectionné, mais comment puis-je décocher les éléments cochés d'une vue de navigation?
Cela désélectionnera les éléments:
int size = mNavigationView.getMenu().size();
for (int i = 0; i < size; i++) {
mNavigationView.getMenu().getItem(i).setChecked(false);
}
J'ai vu la solution @arsent et j'ai essayé, et il fera effectivement ce que vous voulez, à savoir désélectionner tous les éléments ... mais je rencontrais un problème dans le scénario suivant:
NavigationView#setCheckedItem
)NavigationView#setCheckedItem
)Dans ce scénario, l'élément 1 ne sera pas marqué comme vérifié. En effet, en mode interne, la vue de navigation garde trace du jeu d’éléments précédemment sélectionné à l’étape 1, qui ne change pas à l’étape 2, et ignore simplement l’étape 3, car l’élément précédemment sélectionné est identique à celui que nous sélectionnons maintenant.
Ma suggestion (et une solution alternative) pour éviter cela consiste simplement à avoir un élément invisible factice et à utiliser NavigationView#setCheckedItem
pour sélectionner cet élément chaque fois que vous souhaitez tout désélectionner, comme ci-dessous.
<item
Android:id="@+id/menu_none"
Android:title=""
Android:visible="false"/>
Pour tout désélectionner, il suffit de
mNavigationView.setCheckedItem(R.id.menu_none);
Pour décocher tous les éléments MenuItems
, y compris SubMenu
, vous devez utiliser la récursivité -
private void unCheckAllMenuItems(@NonNull final Menu menu) {
int size = menu.size();
for (int i = 0; i < size; i++) {
final MenuItem item = menu.getItem(i);
if(item.hasSubMenu()) {
// Un check sub menu items
unCheckAllMenuItems(item.getSubMenu());
} else {
item.setChecked(false);
}
}
}
Appelez la méthode ci-dessus pour désélectionner tous les éléments, comme ci-dessous -
unCheckAllMenuItems(navigationView.getMenu());
juste rendre vos articles non vérifiables comme si
<item
Android:id="@+id/profile_item"
Android:checkable="false"
Android:title="@string/profile"/>
Citant @Codeversed, il n'y a " pas besoin de boucler les éléments de menu avec une surcharge ajoutée! ". Cependant, il n'est pas nécessaire de créer plusieurs groupes (dans ce cas, il crée le @+id/grp1
et le @+id/grp2
) pour décocher un élément précédemment sélectionné.
Vous pouvez simplement ajouter un seul groupe pour tous les éléments avec le Android:checkableBehavior
, comme ceci:
<group Android:checkableBehavior="single">
<item
Android:id="@+id/id1"
Android:checked="true"
Android:icon="@drawable/drawable1"
Android:title="@string/string1" />
<item
Android:id="@+id/id2"
Android:icon="@drawable/drawable2"
Android:title="@string/string2" />
</group>
Les solutions de Joao ne m'ont pas fonctionné comme prévu. Cela créerait un espace vide à partir de la vue d'élément non contrôlée dans ma navigation.
Assurez-vous simplement de définir la vue comme disparue:
<item
Android:id="@+id/your_menu_item_id_to_hide"
Android:title=""
Android:visible="false"/>
bottomNavigationView.getMenu().findItem(R.id.your_menu_item_id_to_hide).setChecked(true);
bottomNavigationView.findViewById(R.id.your_menu_item_id_to_hide).setVisibility(View.GONE);
Une solution Arsent n'est pas nécessaire dans ce cas.
Je suppose que quelqu'un comme moi utilise ces méthodes comme ça
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_today:
break;
case R.id.nav_calendar:
navigationView.getMenu().performIdentifierAction(R.id.nav_today, 0);
navigationView.getMenu().getItem(0).setChecked(true);//or
navigationView.setCheckedItem(R.id.nav_today);//or
drawerLayout.closeDrawers();
break;
}
return true;
}
Essayer de vérifier R.id.nav_today
après avoir cliqué sur R.id.nav_calendar
, (au fait: checkableBehavior="single"
), malheureusement cela ne fonctionnera pas.
En effet, après avoir appelé votre code navigationView.setCheckedItem(R.id.nav_today)
, le R.id.nav_today
sera vérifié immédiatement, mais après cela, votre clic sur R.id.nav_calendar
se vérifiera.
C'est pourquoi les méthodes que vous utilisez ne semblent jamais fonctionner du tout. C'est un travail, mais soyez prioritaire immédiatement.
Pour le décocher dans NavigationItemSelectedListener
, je devais utiliser post (sur le fil de l'interface utilisateur):
App.getHandler().post(() -> menuItem.setChecked(false));
Exemple complet:
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(
menuItem -> {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
switch (menuItem.getItemId()) {
...
}
App.getHandler().post(() -> menuItem.setChecked(false));
return true;
});
p.s. dans mon cas, App.getHandler()
renvoie l'instance Handler
pour l'interface utilisateur Thread Lopper
je combine les réponses @arsent et @Rahul et écris ce code:
private void NavigationView_NavigationItemSelected(object sender, NavigationView.NavigationItemSelectedEventArgs e)
{
var size = navigationView.Menu.Size();
for (int i = 0; i < size; i++)
{
var item= navigationView.Menu.GetItem(i).SetChecked(false);
if (item.HasSubMenu)
{
for (int j = 0; j < item.SubMenu.Size(); j++)
{
item.SubMenu.GetItem(j).SetChecked(false);
}
}
}
e.MenuItem.SetChecked(true);
drawerLayout.CloseDrawers();
}
le code ci-dessus est pour xamarin c # et fonctionne, mais vous pouvez facilement convertir en Java
Tout ce que vous avez à faire est d’entourer vos groupes de la manière suivante:
<group>
<group
Android:id="@+id/grp1">
<item
Android:id="@+id/nav_profile"
Android:icon="@drawable/ic_account_circle_24dp"
Android:title="@string/profile" />
</group>
<group
Android:id="@+id/grp2">
<item
Android:id="@+id/nav_settings"
Android:icon="@drawable/ic_settings_24dp"
Android:title="@string/settings" />
<item
Android:id="@+id/nav_help"
Android:icon="@drawable/topic_help"
Android:title="@string/help_feedback" />
</group>
</group>
Pas besoin de mettre en boucle des éléments de menu avec une surcharge supplémentaire!