如何实现点击Toolbar菜单项后将其动态替换为其他菜单项?
Toolbar 编辑/保存菜单项动态切换实现
不需要动态移除、新增菜单项,直接在菜单资源里预定义两个按钮,通过visible属性动态控制显隐即可,性能比动态add/remove更稳定,不会出现菜单闪烁问题,实现逻辑如下:
- 第一步:编写菜单资源文件
在res/menu目录下新建菜单配置文件,同时放入编辑、保存两个菜单项,默认隐藏保存按钮:
<?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"> <item android:id="@+id/action_edit" android:icon="@drawable/ic_edit" android:title="编辑" app:showAsAction="always"/> <item android:id="@+id/action_save" android:icon="@drawable/ic_save" android:title="保存" android:visible="false" app:showAsAction="always"/> </menu>
- 第二步:在界面中初始化菜单与状态标记
在承载TextView的Activity/Fragment中持有菜单实例,定义编辑状态标记位:
private var isEditing = false private var currentMenu: Menu? = null private lateinit var myTextView: TextView // Activity中重写该方法加载菜单 override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.content_detail_menu, menu) currentMenu = menu return true }
如果在Fragment中使用,需要在onCreate生命周期里加一行setHasOptionsMenu(true),否则菜单不会正常加载、点击事件也不会响应。
- 第三步:实现菜单项点击逻辑
处理两个按钮的点击事件,同步切换TextView的编辑状态、菜单项显隐,点击保存时将内容写入SQLite:
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when(item.itemId) { R.id.action_edit -> { // 切换为编辑态 isEditing = true // 配置TextView可输入 myTextView.apply { isFocusable = true isFocusableInTouchMode = true isClickable = true requestFocus() // 弹出软键盘 val inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager inputManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) } // 切换菜单:隐藏编辑,显示保存 currentMenu?.findItem(R.id.action_edit)?.isVisible = false currentMenu?.findItem(R.id.action_save)?.isVisible = true true } R.id.action_save -> { // 收起软键盘 val inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager inputManager.hideSoftInputFromWindow(myTextView.windowToken, 0) // 获取编辑后内容写入SQLite val updatedText = myTextView.text.toString() val db = yourSQLiteOpenHelper.writableDatabase val contentValues = ContentValues().apply { put("content", updatedText) } // 替换为你自己的表名、更新匹配条件 db.update("your_table", contentValues, "id = ?", arrayOf(targetDataId.toString())) db.close() // 切回只读态 isEditing = false myTextView.apply { isFocusable = false isFocusableInTouchMode = false isClickable = false clearFocus() } // 切换菜单:隐藏保存,显示编辑 currentMenu?.findItem(R.id.action_edit)?.isVisible = true currentMenu?.findItem(R.id.action_save)?.isVisible = false true } else -> super.onOptionsItemSelected(item) } }
踩坑提示:不要每次切换状态都调用
invalidateOptionsMenu()重建菜单,直接修改已有菜单项的isVisible属性即可,响应速度更快,也不会出现UI跳变问题。
内容的提问来源于stack exchange,提问作者nano tech
相关产品推荐
相关产品推荐

