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

Toolbar菜单点击两次才触发onOptionsItemSelected的问题咨询

问题原因及解决方案

这个问题我之前做Toolbar菜单扩展的时候也踩过坑,原因确实和你在onMenuOpened里修改SHOW_AS_ACTION_ALWAYS的时机有关:

当你点击溢出菜单时,系统已经进入了菜单打开的流程,onMenuOpened回调触发时,菜单UI已经开始渲染。这时候你突然修改所有菜单项的showAsAction属性,Android的Menu组件会立即触发UI重绘——原来的溢出下拉布局会被替换成直接显示所有图标的布局。你的第一次点击其实是落在了正在重绘的过渡UI上,系统把这次点击当作是菜单状态更新的一部分,并没有触发菜单项的点击事件;等重绘完成后,第二次点击才会被正确识别,调用onOptionsItemSelected。

正确的解决方案:在菜单准备阶段修改显示状态

不要在菜单已经打开后再修改布局,而是在菜单准备阶段就完成显示状态的调整。可以用一个标志位来控制菜单的展开/收起状态,然后通过invalidateOptionsMenu()通知系统重新准备菜单:

  1. 定义一个标志位标记菜单状态:
private var isMenuExpanded = false
  1. 处理溢出菜单项的点击,切换状态并通知菜单重绘:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when(item.itemId) {
        R.id.action_overflow -> {
            // 切换展开/收起状态
            isMenuExpanded = !isMenuExpanded
            // 通知系统重新准备菜单
            invalidateOptionsMenu()
            true
        }
        // 处理其他菜单项的点击逻辑
        else -> super.onOptionsItemSelected(item)
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 09:13:18