如何确保onCreateOptionsMenu仅在Activity启动时调用一次?
核心思路
问题根源是Bottom Sheet Fragment显示时会触发Activity的菜单重绘流程,我们需要从控制Activity菜单初始化时机和隔离Fragment对Activity菜单的影响两个维度解决。
具体解决方案
1. 给Activity加初始化标记,限制菜单创建仅执行一次
在Activity中添加一个布尔标记,确保onCreateOptionsMenu里的初始化逻辑只在首次进入时执行:
private var isMenuInitialized = false override fun onCreateOptionsMenu(menu: Menu): Boolean { if (!isMenuInitialized) { // 这里写你的菜单初始化代码,比如加载菜单布局 menuInflater.inflate(R.menu.main_activity_menu, menu) isMenuInitialized = true } return true }
2. 禁止Bottom Sheet Fragment影响Activity菜单
在Bottom Sheet Fragment的onCreate或onViewCreated方法中,明确设置不启用自身的选项菜单,避免触发Activity的菜单重绘:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 告诉系统该Fragment不需要处理选项菜单 setHasOptionsMenu(false) }
3. 排查并移除不必要的invalidateOptionsMenu()调用
如果你的代码中存在调用invalidateOptionsMenu()的地方(包括Activity或Fragment中),非必要情况下直接删除——这个方法会强制触发菜单重绘,是导致onCreateOptionsMenu重复执行的常见原因。
4. 使用MenuProvider时确保仅注册一次
如果用的是AndroidX的MenuProvider(替代旧的菜单回调),务必只在Activity的onCreate方法中注册一次,绑定合适的生命周期状态:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 仅在Activity创建时注册一次MenuProvider addMenuProvider(object : MenuProvider { override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { // 菜单初始化逻辑,只会执行一次 menuInflater.inflate(R.menu.main_activity_menu, menu) } override fun onMenuItemSelected(menuItem: MenuItem): Boolean { // 菜单点击事件处理 return when (menuItem.itemId) { R.id.action_settings -> { // 处理设置点击 true } else -> false } } }, this, Lifecycle.State.STARTED) }
额外说明
如果Bottom Sheet Fragment需要自己的选项菜单,完全可以在Fragment内部独立实现:设置setHasOptionsMenu(true),并重写Fragment的onCreateOptionsMenu和onOptionsItemSelected,这种情况下Activity的菜单不会被干扰重绘。
内容的提问来源于stack exchange,提问作者Ayushi Paul
相关产品推荐
相关产品推荐

