Navigation Component结合ContextMenu导致Toolbar重复显示问题求助
我有一个关联了Navigation Component的MainActivity,每个Fragment都拥有独立的Toolbar实现,通过调用Activity中定义的如下setupToolbar方法来配置Toolbar:
fun setupToolbar(toolbar: Toolbar) { setSupportActionBar(toolbar) supportActionBar?.setDisplayShowTitleEnabled(false) NavigationUI.setupActionBarWithNavController(this, navController) setupActionBarWithNavController(navController) }
目前功能运行正常,但在添加长按列表项唤起的ContextMenu后,出现了Toolbar重复显示的问题(见附图)。请问如何避免该重复现象?为何ContextMenu不沿用之前配置好的Toolbar?
重复Toolbar的成因
唤起ContextMenu时,系统会默认尝试创建系统级ActionBar来承载ContextMenu操作选项,而你已通过setSupportActionBar(toolbar)将自定义Toolbar设为Activity的ActionBar,若主题未彻底禁用系统ActionBar,就会同时显示自定义Toolbar和系统临时生成的ActionBar,造成重复。另外,setupToolbar方法中重复调用了两次setupActionBarWithNavController,属于冗余代码,建议删除其中一行。
解决重复显示的方法
1. 显式指定ContextMenu使用自定义Toolbar
在唤起ContextMenu的Fragment中,重写onCreateContextMenu,指定用当前Fragment的自定义Toolbar作为ContextMenu的载体:
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) { super.onCreateContextMenu(menu, v, menuInfo) // 获取当前Fragment的自定义Toolbar val toolbar = requireView().findViewById<Toolbar>(R.id.your_fragment_toolbar_id) // 将Toolbar设为ContextMenu的头部/载体 menu.setHeaderView(toolbar) // 加载ContextMenu菜单 menuInflater.inflate(R.menu.your_context_menu, menu) }
2. 用主题彻底禁用系统默认ActionBar
在styles.xml中设置Activity主题为NoActionBar类型,从根源避免系统自动生成ActionBar:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- 其他主题配置项 --> </style>
3. 统一Activity中Toolbar的配置逻辑
修改MainActivity的setupToolbar方法,移除冗余调用,并提前配置Toolbar与ContextMenu的关联:
fun setupToolbar(toolbar: Toolbar) { setSupportActionBar(toolbar) supportActionBar?.setDisplayShowTitleEnabled(false) // 仅保留一次Navigation关联调用 NavigationUI.setupActionBarWithNavController(this, navController) // 绑定Toolbar的ContextMenu监听,后续可统一处理 toolbar.setOnCreateContextMenuListener { menu, v, menuInfo -> // 可在此统一加载菜单,或留空由Fragment自行实现 } }
为什么ContextMenu不沿用已配置的Toolbar?
系统默认的ContextMenu机制独立于自定义Toolbar配置,它会优先使用系统级ActionBar(若主题允许),不会自动关联你通过setSupportActionBar设置的自定义Toolbar。只有通过显式指定载体,才能让ContextMenu复用已配置好的Toolbar。
内容的提问来源于stack exchange,提问作者Jumpa

