Как снять отметку с отмеченных пунктов в навигационном представлении?
Я знаю, что можно выделить элемент представления навигации, позвонив setCheckedItem()
или вернуть истинное значение в onNavigationItemSelected
отображать элемент как выбранный элемент, но как я могу снять флажки с отмеченных элементов в представлении навигации?
10 ответов
Это снимет галочки с пунктов:
int size = mNavigationView.getMenu().size();
for (int i = 0; i < size; i++) {
mNavigationView.getMenu().getItem(i).setChecked(false);
}
Я увидел решение @arsent и попробовал, и он действительно сделает то, что вы хотите, то есть отменить выбор всех элементов... но у меня возникла проблема в следующем сценарии:
- Выберите пункт меню 1 (используя
NavigationView#setCheckedItem
) - Отмените выбор всех элементов в соответствии с решением @ arsent
- Снова выберите пункт меню 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);
Снять все 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());
Просто сделайте свои вещи не проверяемыми, как это так
<item
android:id="@+id/profile_item"
android:checkable="false"
android:title="@string/profile"/>
Цитируя @Codeversed, "нет необходимости зацикливать пункты меню с дополнительными издержками!". Но нет необходимости создавать несколько групп (в этом случае он создает @+id/grp1
а также @+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>
Решения Хуана не сработали для меня, как ожидалось. Это привело бы к пустому пространству от непроверенного Представления Пункта на моей Навигации.
Просто убедитесь, что установили представление как пропавшее:
<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 не требуется.
Все, что вам нужно сделать, это окружить ваши группы следующим образом:
<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>
Не нужно зацикливать пункты меню с дополнительными накладными расходами!
Снять галочку внутри 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
Я думаю, кто-то, как я, использует эти методы так же, как это
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"
), к сожалению, это не сработает.
Это потому, что после вашего кода navigationView.setCheckedItem(R.id.nav_today)
называться тогда R.id.nav_today
будет проверен сразу, но после этого, вы нажмете на R.id.nav_calendar
проверим себя.
Вот почему методы, которые вы используете, кажется, никогда не работают вообще. Это работа, но немедленно переопределите.
Мне пришлось использовать комбинацию всех упомянутых здесь решений. В моем случае я хочу открыть намерение URL-адреса при щелчке элемента (открыть браузер). Выбранный элемент должен быть снят после щелчка и сброшен к элементу ранее. Важно понимать, что вы не можете снять отметку с элемента во время события прослушивателя кликов, поскольку отмеченное состояние будет обработано впоследствии. Итак, это мое решение в Котлине:
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.
@arsent ответ правильный, но setCheckable(false) снимает отметку со всех элементов, это предотвращает проверку элементов в будущем.
Просто используйте setChecked(false)
int size = mNavigationView.getMenu().size();
for (int i = 0; i < size; i++) {
mNavigationView.getMenu().getItem(i).setChecked(false);
}
Я комбинирую ответы @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 C# и работает, но вы можете легко конвертировать в Java