Toolbar菜单点击两次才触发onOptionsItemSelected的问题咨询
问题原因及解决方案
这个问题我之前做Toolbar菜单扩展的时候也踩过坑,原因确实和你在onMenuOpened里修改SHOW_AS_ACTION_ALWAYS的时机有关:
当你点击溢出菜单时,系统已经进入了菜单打开的流程,onMenuOpened回调触发时,菜单UI已经开始渲染。这时候你突然修改所有菜单项的showAsAction属性,Android的Menu组件会立即触发UI重绘——原来的溢出下拉布局会被替换成直接显示所有图标的布局。你的第一次点击其实是落在了正在重绘的过渡UI上,系统把这次点击当作是菜单状态更新的一部分,并没有触发菜单项的点击事件;等重绘完成后,第二次点击才会被正确识别,调用onOptionsItemSelected。
正确的解决方案:在菜单准备阶段修改显示状态
不要在菜单已经打开后再修改布局,而是在菜单准备阶段就完成显示状态的调整。可以用一个标志位来控制菜单的展开/收起状态,然后通过invalidateOptionsMenu()通知系统重新准备菜单:
- 定义一个标志位标记菜单状态:
private var isMenuExpanded = false
- 处理溢出菜单项的点击,切换状态并通知菜单重绘:
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when(item.itemId) { R.id.action_overflow -> { // 切换展开/收起状态 isMenuExpanded = !isMenuExpanded // 通知系统重新准备菜单 invalidateOptionsMenu() true } // 处理其他菜单项的点击逻辑 else -> super.onOptionsItemSelected(item) } }
- 在
onPrepareOptionsMenu中根据标志位设置菜单项的显示方式:
override fun onPrepareOptionsMenu(menu: Menu): Boolean { menu.forEach { menuItem -> if (menuItem.actionView == null) { // 根据展开状态设置显示方式 val showAsActionFlag = if (isMenuExpanded) { MenuItem.SHOW_AS_ACTION_ALWAYS } else { MenuItem.SHOW_AS_ACTION_NEVER // 或者你原来的默认显示方式 } menuItem.setShowAsAction(showAsActionFlag) } } // 可选:展开后隐藏溢出按钮,优化体验 menu.findItem(R.id.action_overflow)?.isVisible = !isMenuExpanded return super.onPrepareOptionsMenu(menu) }
这样修改后,菜单会在打开前就完成布局调整,打开后的UI是最终状态,点击一次菜单项就能正常触发onOptionsItemSelected,不会出现需要点击两次的问题。
内容的提问来源于stack exchange,提问作者Amin
相关产品推荐
相关产品推荐

