web-dev-qa-db-fra.com

Comment décocher les éléments cochés dans la vue Navigation?

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?

27
Hafez Divandari

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

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:

  1. Sélectionnez l'élément de menu 1 (en utilisant NavigationView#setCheckedItem)
  2. Désélectionnez tous les éléments selon la solution de @ arsent
  3. Sélectionnez à nouveau l'élément de menu 1 (en utilisant 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);
27
Joao Sousa

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());
17
Rahul

juste rendre vos articles non vérifiables comme si

<item
    Android:id="@+id/profile_item"
    Android:checkable="false"
    Android:title="@string/profile"/>
6
Jack

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>

2

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.

1
Victor R. Oliveira

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.

1
KDLin

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

0
user924

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

0
arman

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! 

0
Codeversed