Android Kotlin如何实现ActionBar图标点击互隐及修复返回键崩溃
问题修复方案
问题梳理
当前代码存在两个核心问题:
- 未持有菜单项实例,无法在点击回调中动态控制两个ActionBar图标的显隐状态,未实现互斥切换逻辑
onOptionsItemSelected的when分支没有覆盖默认场景,当系统派发ActionBar返回按钮(android.R.id.home)事件时,会抛出NoWhenBranchMatchedException导致Activity崩溃,这是返回键触发崩溃的直接原因
具体实现代码
第一步:声明必要的成员变量
在Activity类中添加菜单引用和编辑状态标记:
// 两个ActionBar菜单项引用 private lateinit var editMenuItem: MenuItem private lateinit var updateMenuItem: MenuItem // 编辑状态标记,用于返回键逻辑判断 private var isEditMode = false
第二步:重写菜单创建方法获取菜单项实例
override fun onCreateOptionsMenu(menu: Menu?): Boolean { // 替换成你自己的菜单xml文件名 menuInflater.inflate(R.menu.operation_menu, menu) editMenuItem = menu!!.findItem(R.id.edit_icon) updateMenuItem = menu.findItem(R.id.update_icon) // 默认状态下隐藏更新按钮,只显示编辑按钮 updateMenuItem.isVisible = false return super.onCreateOptionsMenu(menu) }
第三步:补全菜单点击回调逻辑
补全显隐切换逻辑,同时补全缺失的分支匹配,避免崩溃:
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.edit_icon -> { // 原有编辑状态逻辑 name.isEnabled = true name.isFocusableInTouchMode = true phone.isEnabled = true phone.isFocusableInTouchMode = true cameraIcon.visibility = View.VISIBLE // 菜单互斥切换:隐藏编辑按钮,显示更新按钮 editMenuItem.isVisible = false updateMenuItem.isVisible = true isEditMode = true true } R.id.update_icon -> { // 这里写你的信息提交更新逻辑,比如提交网络请求 // 提交完成后切换菜单状态:显示编辑按钮,隐藏更新按钮 editMenuItem.isVisible = true updateMenuItem.isVisible = false isEditMode = false true } // 处理ActionBar返回按钮事件,避免分支匹配异常崩溃 android.R.id.home -> { onBackPressedDispatcher.onBackPressed() true } // 补全默认分支,所有未匹配的菜单事件交给父类处理,彻底解决崩溃 else -> super.onOptionsItemSelected(item) } }
第四步:重写返回键逻辑,适配编辑状态退出
如果处于编辑状态时按返回键,需要同步退出编辑状态、恢复UI:
@Deprecated("Deprecated in Java") override fun onBackPressed() { if (isEditMode) { // 退出编辑状态,恢复UI name.isEnabled = false name.isFocusableInTouchMode = false phone.isEnabled = false phone.isFocusableInTouchMode = false cameraIcon.visibility = View.GONE // 恢复菜单默认状态 editMenuItem.isVisible = true updateMenuItem.isVisible = false isEditMode = false return } super.onBackPressed() }
注意点
- Kotlin开发中可以直接用属性访问语法替代Java风格的setXXX/getXXX方法,不需要手动写分号
- 用
when做分支判断时,如果不是枚举/密封类等明确穷尽分支的场景,必须补全else分支,否则很容易出现匹配不到分支的运行时崩溃
内容的提问来源于stack exchange,提问作者AndroidKotlin
相关产品推荐
相关产品推荐

