Как снять отметку с отмеченных элементов в режиме навигации?

Я знаю, что можно выделить элемент навигации, вызвав setCheckedItem() или вернуть истинное значение в onNavigationItemSelected чтобы отобразить элемент в качестве выбранного элемента, но как я могу снять флажки с отмеченными элементами навигационного представления?

Ответы

Ответ 1

Это снимет галочки с пунктов:

    int size = mNavigationView.getMenu().size();
    for (int i = 0; i < size; i++) {
        mNavigationView.getMenu().getItem(i).setCheckable(false);
    }

Ответ 2

Я увидел решение @arsent и дал ему попробовать, и он действительно сделает то, что вы хотите, чтобы отменить выбор всех элементов... но у меня возникла проблема в следующем сценарии:

  1. Выберите пункт меню 1 (с помощью NavigationView#setCheckedItem)
  2. Отменить выбор всех элементов в соответствии с решением @arsent
  3. NavigationView#setCheckedItem раз выберите пункт меню 1 (с помощью NavigationView#setCheckedItem)

В этом случае элемент 1 не будет отмечен как отмеченный. Это потому, что изнутри навигационное представление отслеживает ранее выбранный элемент, установленный на шаге 1, который не изменяется на шаге 2, и он просто пропускает шаг 3, потому что ранее выбранный элемент совпадает с тем, который мы сейчас выбираем.

Мое предложение (и альтернативное решение), чтобы избежать этого, просто имеет фиктивный невидимый элемент и использует NavigationView#setCheckedItem для выбора этого элемента, когда вы хотите отменить выбор всех, например

<item
    android:id="@+id/menu_none"
    android:title=""
    android:visible="false"/>

Отменить выбор всего, что нужно сделать

mNavigationView.setCheckedItem(R.id.menu_none);

Ответ 3

Чтобы снять SubMenu элементов MenuItems включая элементы SubMenu, вы должны использовать рекурсию -

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

Вызовите метод выше, чтобы снять отметку со всех элементов, например ниже -

unCheckAllMenuItems(navigationView.getMenu());

Ответ 4

просто сделайте свои вещи незаметными, например, так

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

Ответ 5

Цитируя @Codeversed, нет необходимости в создании элементов меню с добавленными накладными расходами! ". Но нет необходимости создавать несколько групп (в этом случае он создает @+id/grp1 и @+id/grp2), чтобы снять @+id/grp2 с предыдущего отмеченного элемента.

Вы можете просто добавить одну группу для всех элементов с android:checkableBehavior, например:

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

Ответ 6

Решения Joao не работали для меня как полностью ожидаемые. Это приведет к простому пробелу из непроверенного элемента "Вид" в моей навигации.

Просто не забудьте установить вид как ушедший:

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

Решение Arsent в этом случае не требуется.

Ответ 7

Я думаю, кто-то вроде меня использует эти методы, как это

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

Попытка проверить R.id.nav_today после того, как вы нажали на R.id.nav_calendar, (checkableBehavior="single": checkableBehavior="single"), к сожалению, это не сработает.

Это связано с тем, что после navigationView.setCheckedItem(R.id.nav_today) кода navigationView.setCheckedItem(R.id.nav_today) тогда R.id.nav_today будет проверена немедленно, но после этого ваш клик по R.id.nav_calendar проверяет себя.

Вот почему любые методы, которые вы используете, никогда не работают вообще. Это работа, но нужно немедленно переопределить ее.

Ответ 8

Все, что вам нужно сделать, это окружить ваши группы следующим образом:

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

Не нужно зацикливать элементы меню с дополнительными накладными расходами!

Ответ 9

Я совмещаю ответы @arsent и @Rahul и пишу этот код:

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

        }

выше код для xamarin С# и работает, но вы можете легко преобразовать в java

Ответ 10

Чтобы снять флажок внутри NavigationItemSelectedListener мне пришлось использовать сообщение (в ветке пользовательского интерфейса):

App.getHandler().post(() -> menuItem.setChecked(false));

Полный пример:

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

ps в моем случае App.getHandler() возвращает экземпляр Handler для UI Thread Lopper

Ответ 11

Мне пришлось использовать комбинацию всех решений, упомянутых здесь. В моем случае я хочу открыть URL Intent при щелчке элемента (откройте браузер). Выбранный элемент должен быть снят с проверки после нажатия и сброшен до элемента ранее. Важно понимать, что вы не можете снять отметку с элемента во время события прослушивания щелчка, так как проверенное состояние будет обработано впоследствии. Вот мое решение в Котлине:

        val item = navigationView.menu.findItem(R.id.menu_item)
        item.setOnMenuItemClickListener {

            val oldItem = navigationView.checkedItem
            rootView.postDelayed({ // you can use here any View to post a Runnable with a delay
                navigationView.setCheckedItem(oldItem?.itemId ?: R.id.default_item)
            }, 500)
            browseURL("https://www.example.com")
            true
        }

Я использую Навигационный ящик в сочетании с Jetpack Navigation.