Android NavigationDrawer结合Toolbar时自定义选项菜单不显示问题咨询
核心问题定位
你遇到的菜单不显示、双Toolbar的问题,本质是两级嵌套导航架构下的菜单分发链路断裂:
你当前的层级是 外层MainActivity → 主导航 → DrawerFragment → DrawerFragment内部通过childFragmentManager托管三个独立的子导航图(home/rocket/company)。当子导航图下的CompanyFragment调用setHasOptionsMenu(true)提交菜单请求时,因为动态切换NavController的过程中没有触发ActionBar的菜单刷新,导致提交的菜单没有被加载到全局Toolbar上;而你自己在内容Fragment里加独立Toolbar的操作,直接绕过了全局Toolbar的绑定逻辑,自然出现了两个Toolbar的显示问题。
具体修改方案
- 1. 子Fragment侧的菜单逻辑修正
打开CompanyFragment的onCreate方法,不要做任何独立Toolbar的初始化,保留原有的setHasOptionsMenu(true)逻辑,确保菜单请求能正确分发给宿主Activity:
不要在这个Fragment的布局里加任何Toolbar控件,所有Toolbar的初始化、导航关联统一放到外层DrawerFragment处理。override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 保留原有逻辑,显式开启选项菜单 setHasOptionsMenu(true) Repo.init(requireContext()) } - 2. NavController切换时主动刷新ActionBar菜单
找到DrawerFragment里观察子导航控制器的代码块,在每次关联新的NavController到Toolbar之后,主动触发Activity的菜单重建,解决缓存不刷新的问题:
原代码位置:
修改为:controller.observe( viewLifecycleOwner, { navController -> NavigationUI.setupWithNavController( binding.toolbarHome, navController, binding.drawerLayout ) drawerSelectedItemId = navController.graph.id } )controller.observe( viewLifecycleOwner, { navController -> NavigationUI.setupWithNavController( binding.toolbarHome, navController, binding.drawerLayout ) // 关键:强制ActionBar重新加载所有关联Fragment的选项菜单 requireActivity().invalidateOptionsMenu() drawerSelectedItemId = navController.graph.id } ) - 3. 排查菜单被折叠的边界情况
你当前menu/company里的刷新项配置了app:showAsAction="ifRoom|withText",如果Toolbar上的标题文本过长,系统会自动把这个菜单项折叠到右上角的三点溢出菜单里,看起来就像“菜单没显示”。可以临时把配置改成app:showAsAction="always"做测试,确认显示正常后再根据UI设计要求改回ifRoom。
最终效果
修改完成后,同一个Toolbar会自动承担两种职责:
- 左侧的汉堡按钮/返回箭头:由
NavigationUI.setupWithNavController自动关联DrawerLayout处理,点击可以正常打开/关闭导航抽屉 - 右侧的操作按钮:由当前显示的内容Fragment(比如CompanyFragment)提交的自定义菜单自动加载,不需要单独初始化Toolbar
注意:整个页面层级里只保留DrawerFragment布局里的这一个MaterialToolbar实例,不要在任何内容Fragment里重复调用
setSupportActionBar,否则会直接打断原有的导航和菜单绑定逻辑。
内容的提问来源于stack exchange,提问作者Sorry
相关产品推荐
相关产品推荐

