我正试图从弃用的setHasOptionsMenu()
/onCreateOptionsMenu()
方法迁移到新的addMenuProvider()
/onCreateMenu()
方法,以便显示片段中的选项菜单。使用新的API,当我在两个都实现MenuProvider
的片段之间导航时,操作栏中的图标会出现难看的延迟/闪烁。
我认为这是由异步生命周期回调引起的:新片段的菜单可能在旧片段的Lifecycle.Event.ON_DESTROY
事件触发删除旧菜单项之前被膨胀和添加,从而导致两个菜单同时处于活动状态。然而,我不知道如何避免这种行为。我尝试在每个片段中从onDestroyView()
调用removeMenuProvider()
和invalidateOptionsMenu()
,但没有成功。我还尝试将addMenuProvider()
移动到onViewCreated()
而不是onCreateView()
。旧setHasOptionsMenu()
API未出现此问题。
最小重建:
- 打开Android Studio,创建一个新项目,然后选择"底部导航活动;模板
- 创建两个菜单资源文件,每个文件至少包含一个带有图标和
app:showAsAction="always"
的菜单项 - 在底部导航控制器显示的两个片段中,从
onCreateView()
中调用以下内容:
requireActivity().addMenuProvider(object: MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(/* one of the menus from step 2 */, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return false
}
}, viewLifecycleOwner)
- 运行应用程序并使用底部导航栏在这些片段之间切换。你应该看到这样的东西:示例gif
从Buganizer上的一些好人那里得到了答案:请参阅https://issuetracker.google.com/issues/243679672.
简而言之,使用addMenuProvider(/* provider */, viewLifecycleOwner, Lifecycle.State.RESUMED)
使用addMenuProvider(/* provider */, viewLifecycleOwner, Lifecycle.State.STARTED)
似乎可以防止出现菜单图标不可见的短暂时刻(同时也可以防止菜单重叠(,尽管这似乎与上面链接中描述的动画期间发生的生命周期状态转换相矛盾。。。