You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何动态添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 07:45:06