我知道可以通过调用setCheckedItem()
来突出显示导航视图项目,或者在onNavigationItemSelected
中返回true值以将项目显示为所选项目,但是如何取消选中已选中的项目导航视图的项目?
答案 0 :(得分:47)
这将取消选中项目:
int size = mNavigationView.getMenu().size();
for (int i = 0; i < size; i++) {
mNavigationView.getMenu().getItem(i).setCheckable(false);
}
答案 1 :(得分:28)
我看到@arsent解决方案并尝试了一下,它确实会做你想要的,即取消选择所有项目......但是,我在以下场景中遇到了问题:
NavigationView#setCheckedItem
)NavigationView#setCheckedItem
)在这种情况下,第1项不会被标记为已选中。这是因为导航视图在内部跟踪在步骤1中设置的先前选择的项目,在步骤2中没有改变,并且它只是跳过步骤3,因为先前选择的项目与步骤3相同我们现在正在选择。
我的建议(以及另一种解决方案)避免这种情况只是拥有一个虚拟的隐形物品,并且只要您想要取消全部选择,就可以使用NavigationView#setCheckedItem
选择该项目,如此
<item
android:id="@+id/menu_none"
android:title=""
android:visible="false"/>
取消选择所有只做
mNavigationView.setCheckedItem(R.id.menu_none);
答案 2 :(得分:17)
要取消选中包含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());
答案 3 :(得分:6)
只是让你的物品不可检查
<item
android:id="@+id/profile_item"
android:checkable="false"
android:title="@string/profile"/>
答案 4 :(得分:2)
引用@Codeversed,有&#34; 无需循环添加开销菜单项!&#34;。但是,不需要创建多个组(在这种情况下,他正在创建@+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>
答案 5 :(得分:1)
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解决方案。
答案 6 :(得分:1)
我想像我这样的人会像这样使用这些方法
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
会自行检查。
这就是为什么你使用的任何方法似乎永远不会起作用的原因。这是工作,但要立即覆盖。
答案 7 :(得分:0)
您需要做的就是像这样围绕您的群组:
<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>
无需循环添加额外的菜单项!
答案 8 :(得分:0)
我结合了@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#和work的,但你可以很容易地转换为java
答案 9 :(得分:0)
要在NavigationItemSelectedListener
内取消选中它,我必须使用post(到UI线程):
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;
});
p.s。在我的情况下,App.getHandler()
返回了Handler
个UI线程Lopper实例
答案 10 :(得分:0)
我不得不结合使用这里提到的所有解决方案。就我而言,我想在单击项目时打开URL意图(打开浏览器)。单击后应取消选中的项目,然后再重置为该项目。重要的是要了解,您不能在单击侦听器事件期间取消选中某个项目,因为此后将处理选中状态。这是我在Kotlin中的解决方案:
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
}
答案 11 :(得分:0)
@arsent的答案是正确的,但setCheckable(false)取消选中所有项目,这防止将来再次检查项目。
只需使用setChecked(false)
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.drawerlayout.widget.DrawerLayout
import com.example.tender.R
import com.example.tender.databinding.FragmentAvailableTenderBinding
import com.example.tender.databinding.FragmentLoginBinding
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.NavigationUI
/**
* A simple [Fragment] subclass.
*/
class AvailableTenderFragment : Fragment() {
private lateinit var drawerLayout: DrawerLayout
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentAvailableTenderBinding.inflate(inflater)
drawerLayout = binding.drawerLayout
**val navController = this.findNavController(R.id.nav_host_fragment)**
**NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)**
NavigationUI.setupWithNavController(binding.navView, navController)
binding.root
}
}