大约一个月前,Android团队弃用了onCreateOptionsMenu
和onOptionsItemSelected
,以及setHasOptionsItemMenu
。不幸的是,这破坏了我所有的代码。
我的应用程序有很多片段,当用户导航到这些片段时,我总是确保菜单项会消失,并在导航回来时重新出现,使用以下代码:
第一个
这段代码运行得很好,而且非常简单。现在Android团队已经弃用了(为什么?)X1 M3 N1 X,我无法重新创建这段代码。
我理解用于膨胀菜单项和处理菜单项单击事件的新语法,尽管我无法弄清楚--我的一生都无法弄清楚--如何在片段中隐藏菜单,然后使用新的菜单提供程序API在导航回来时再次显示它。
以下是我尝试过的方法:
- 导航到片段:*
if (supportFragmentManager.backStackEntryCount == 0) {
supportFragmentManager.commit {
replace(R.id.activityMain_primaryFragmentHost, NewProjectFragment.newInstance(mainSpotlight != null))
addToBackStack(null)
}
}
ActivityFragment
接口中的getRootMenuProvider
函数:*
interface ActivityFragment {
val title: String
companion object {
fun getRootMenuProvider() = object : MenuProvider {
override fun onPrepareMenu(menu: Menu) {
for (_menuItem in menu.children) {
_menuItem.isVisible = false
}
}
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return false
}
}
}
}
- 使用
getRootMenuProvider
函数:*
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(ActivityFragment.getRootMenuProvider())
}
MainActivity
(尝试将菜单项还原到以前的状态):*
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
for (_menu in menu.children) {
_menu.isVisible = true
}
return super.onPrepareOptionsMenu(menu)
}
override fun onBackPressed() {
super.onBackPressed()
findViewById<BottomNavigationView>(R.id.activityMain_bottomNavigationView)?.visibility = View.VISIBLE
invalidateOptionsMenu()
}
这会隐藏片段中的项目,但在导航返回后,这些项目仍然保持隐藏状态,直到用户通过旋转屏幕或执行类似操作重新加载Activity。
如何使用新的菜单提供程序API* 隐藏片段中的菜单项,并在导航返回时重新显示 *?
2条答案
按热度按时间xriantvc1#
短期
所有东西都“坏了”的原因是因为您假设
menu.clear()
和片段菜单调用的分派发生在Activity添加了自己的菜单项之后。片段现在在Activity调用super.onCreateOptionsMenu()
或super.onPrepareOptionsMenu()
时经历菜单调用的分派,所以您可以通过将其作为重写调用的最后而不是第一次调用来“修复”您的问题。长期
事实上,你做错了很多:由Activity控制的全局菜单是一个共享资源,任何单独的片段都不应该手动清除整个菜单。这会破坏Activity菜单项、子片段菜单项以及其他片段的菜单项。只有使某些菜单项膨胀的组件才应该接触这些特定的菜单项。
因此,要解决您的问题,您应该遵循Activity 1.4.0-alpha 01发行说明(该发行版将
MenuHost
和MenuProvider
集成添加到Activity层:AndroidX
ComponentActivity
[及其FragmentActivity
和AppCompatActivity
的子类]现在实现了MenuHost
接口。这允许任何组件通过向Activity添加MenuProvider
示例来向ActionBar
添加菜单项。每个MenuProvider
都可以选择添加一个生命周期,该生命周期将根据Lifecycle
状态和句柄自动控制这些菜单项的可见性当Lifecycle
被销毁时,删除MenuProvider
。他们接着展示了它在片段中的用法:
这特别说明了三件事:
1.一个
MenuProvider
应该只接触它的菜单项。你永远不应该“清除所有菜单项”或者任何影响另一个组件菜单项的操作。1.通过使用生命周期调用
addMenuProvider
(在本例中,是Fragment视图的生命周期--即仅当Fragment视图在屏幕上时才存在的生命周期),那么当Fragment视图被销毁时,您自动隐藏菜单项(当您的replace
调用发生时),并自动在您的片段视图重新出现时(即,当回栈弹出时)重新显示。1.控制
Lifecycle
和菜单项可见性的片段本身应该是创建和处理自己的菜单项的片段。您的Activity(可以添加自己的MenuProvider
,如另一个示例所示)应该只添加Activity的整个生命周期中存在的菜单项(在所有片段上可见的项)。6tdlim6h2#
我有一些片段不需要菜单。因此我清除了菜单。现在似乎没有办法满足这个要求。