如何动态添加NavigationView菜单并处理点击事件与选中高亮效果
解决方案
1. 修正动态菜单创建逻辑
要实现选中高亮,首先需要给动态菜单组开启单选模式,同时给每个菜单项设置可选中属性,建议直接用项目组的projectGroupId作为菜单项的ID(注意不要和现有静态菜单ID冲突),方便后续点击时直接取参数:
private fun addExtraMenu(){ val navView = binding.navView val menu = navView.menu val subMenu = menu.addSubMenu("项目组") // 给项目组菜单组开启单选可选中模式 subMenu.setGroupCheckable(0, true, true) // 替换为你从Room数据库查询到的项目组列表 val projectGroupList = listOf( 100 to "项目组A", 101 to "项目组B", 102 to "项目组C" ) projectGroupList.forEach { (groupId, groupName) -> val menuItem = subMenu.add(0, groupId, 0, groupName) menuItem.isCheckable = true // 按需调用你的角标设置方法 setCounterValueToMenuItem(menuItem, 2) } }
2. 扩展导航选中监听器,同时处理静态/动态菜单逻辑
因为已经用setupWithNavController绑定了导航控制器,不要直接覆盖原生监听器,在原有逻辑基础上扩展动态菜单的跳转和选中处理即可:
private fun setUpNavigation() { val navController = findNavController(R.id.nav_host_fragment_content_main) setSupportActionBar(binding.appBarMain.toolbar) // 把ProjectsFragment的导航ID加入配置,保证顶栏汉堡图标和返回栈正常 val menuItems = mutableListOf( R.id.nav_home, R.id.nav_calendar, R.id.nav_project_browser, R.id.nav_projects ) appBarConfiguration = AppBarConfiguration( menuItems.toSet(), binding.drawerLayout ) setCounterValueToMenuItem(binding.navView.menu.findItem(R.id.nav_home),2) setupActionBarWithNavController(navController, appBarConfiguration) binding.navView.setupWithNavController(navController) // 扩展导航选中监听器 binding.navView.setNavigationItemSelectedListener { menuItem -> // 判断是否是动态添加的项目组菜单项,按你实际的分组ID调整匹配逻辑 if (menuItem.groupId == 0) { val projectGroupId = menuItem.itemId // 跳转ProjectsFragment并携带参数 val bundle = Bundle().apply { putInt("projectGroupId", projectGroupId) } // 注意替换为你自己导航图中ProjectsFragment对应的ID navController.navigate(R.id.nav_projects, bundle) menuItem.isChecked = true binding.drawerLayout.closeDrawers() true } else { // 静态菜单走原生导航逻辑 val handled = NavigationUI.onNavDestinationSelected(menuItem, navController) if (handled) { binding.drawerLayout.closeDrawers() } handled } } // 可选:监听导航变更同步选中状态,避免页面跳转后高亮丢失 navController.addOnDestinationChangedListener { _, destination, arguments -> if (destination.id == R.id.nav_projects) { val groupId = arguments?.getInt("projectGroupId") ?: return@addOnDestinationChangedListener binding.navView.menu.findItem(groupId)?.isChecked = true } } }
注意事项
- 动态菜单的itemId不要和现有静态菜单ID重复,建议静态菜单ID统一设为100以下,项目组ID从100开始分配避免冲突
- 如果项目使用了Safe Args,建议用生成的Directions类传参,比手动拼接Bundle更安全
- Room查询项目组列表需要在IO线程执行,查询完成后再调用
addExtraMenu创建菜单,不要在主线程直接操作数据库
内容的提问来源于stack exchange,提问作者Andreas1234
相关产品推荐
相关产品推荐

