Я знаю, что можно выделить элемент навигации, вызвав setCheckedItem()
или вернуть истинное значение в onNavigationItemSelected
чтобы отобразить элемент в качестве выбранного элемента, но как я могу снять флажки с отмеченными элементами навигационного представления?
Как снять отметку с отмеченных элементов в режиме навигации?
Ответ 1
Это снимет галочки с пунктов:
int size = mNavigationView.getMenu().size();
for (int i = 0; i < size; i++) {
mNavigationView.getMenu().getItem(i).setCheckable(false);
}
Ответ 2
Я увидел решение @arsent и дал ему попробовать, и он действительно сделает то, что вы хотите, чтобы отменить выбор всех элементов... но у меня возникла проблема в следующем сценарии:
- Выберите пункт меню 1 (с помощью
NavigationView#setCheckedItem
) - Отменить выбор всех элементов в соответствии с решением @arsent
-
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.