Skip to content

在 Android 的 Activity 中使用 Menu(选项菜单)可以为用户提供操作入口(如设置、搜索等)。


一、创建菜单资源文件

  1. res/menu 目录下新建 XML 文件(如 main_menu.xml):
    xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <!-- 始终显示在 ActionBar 的图标 -->
        <item
            android:id="@+id/action_search"
            android:icon="@drawable/ic_search"
            android:title="Search"
            app:showAsAction="ifRoom" /> <!-- ifRoom:空间足够时显示图标 -->
    
        <!-- 折叠到溢出菜单(三个点) -->
        <item
            android:id="@+id/action_settings"
            android:title="Settings"
            app:showAsAction="never" /> <!-- never:始终在溢出菜单中 -->
    </menu>

二、在 Activity 中加载菜单

重写 onCreateOptionsMenu 方法,使用 MenuInflater 加载菜单:

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu) // 加载菜单资源
        return true // 返回 true 表示显示菜单
    }
}

三、处理菜单项点击事件

重写 onOptionsItemSelected 方法:

kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_search -> {
            // 处理搜索操作
            Toast.makeText(this, "Search clicked", Toast.LENGTH_SHORT).show()
            true
        }
        R.id.action_settings -> {
            // 处理设置操作
            Toast.makeText(this, "Settings clicked", Toast.LENGTH_SHORT).show()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

四、动态修改菜单项

onPrepareOptionsMenu 中根据条件动态调整菜单:

kotlin
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
    val settingsItem = menu.findItem(R.id.action_settings)
    settingsItem.isVisible = isUserLoggedIn // 根据条件显示/隐藏
    settingsItem.isEnabled = !isProcessing   // 根据条件启用/禁用
    return super.onPrepareOptionsMenu(menu)
}

五、支持 ActionBar

  1. 确保 Activity 使用 AppCompat 主题(在 styles.xml 中):

    xml
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- 其他属性 -->
    </style>
  2. onCreate 中启用 ActionBar

    kotlin
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(binding.toolbar) // 使用自定义 Toolbar(可选)
        supportActionBar?.title = "Main Screen" // 设置标题
    }

六、完整代码示例

1. Activity 代码

kotlin
class MainActivity : AppCompatActivity() {
    private var isUserLoggedIn = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(findViewById(R.id.toolbar))
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_search -> {
                startSearch()
                true
            }
            R.id.action_settings -> {
                openSettings()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onPrepareOptionsMenu(menu: Menu): Boolean {
        menu.findItem(R.id.action_settings).isVisible = isUserLoggedIn
        return super.onPrepareOptionsMenu(menu)
    }

    private fun startSearch() {
        // 实现搜索逻辑
    }

    private fun openSettings() {
        // 跳转到设置界面
    }
}

七、注意事项

  1. 图标资源

    • 将图标文件(如 ic_search.png)放在 res/drawable 目录。
    • 推荐使用 Vector Drawable 以适配不同分辨率。
  2. 兼容性

    • 使用 app:showAsAction 而非 android:showAsAction 以兼容旧版本。
  3. 溢出菜单的文本语言

    • 默认显示为英文(如 "More options"),需在 strings.xml 中覆盖:
      xml
      <string name="abc_action_menu_overflow_description">更多选项</string>
  4. 动态更新菜单

    • 调用 invalidateOptionsMenu() 强制刷新菜单状态。

八、替代方案

  • PopupMenu:实现上下文相关的弹出菜单。

    kotlin
    val popup = PopupMenu(this, anchorView)
    popup.menuInflater.inflate(R.menu.context_menu, popup.menu)
    popup.setOnMenuItemClickListener { /* 处理点击 */ }
    popup.show()
  • BottomNavigationView:更适合底部导航场景。


通过合理使用 Menu,你可以为 Activity 提供清晰的操作入口。如果需要更复杂的菜单交互,可以进一步学习 Navigation ComponentDynamic Menu 相关技术!