OptionsMenu 在方向更改时从片段中消失
OptionsMenu disappears from fragment on orientation change
选项菜单中的图标工作正常,但当您通过旋转屏幕改变方向时,图标会消失。
class SingleRecipeFragment : Fragment() {
private lateinit var viewModel: SingleRecipeViewModel
private lateinit var viewModelFactory: SingleRecipeViewModelFactory
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentSingleRecipeBinding = DataBindingUtil.inflate(inflater,
R.layout.fragment_single_recipe, container, false)
val args =
SingleRecipeFragmentArgs.fromBundle(
requireArguments()
)
val application = requireNotNull(this.activity).application
viewModelFactory =
SingleRecipeViewModelFactory(
args.recipeIndex, application
)
viewModel = ViewModelProvider(this,viewModelFactory)
.get(SingleRecipeViewModel::class.java)
binding.singleRecipeViewModel = viewModel
binding.lifecycleOwner = this
viewModel.curRecipe.observe(viewLifecycleOwner, Observer {
(requireActivity() as MainActivity).toolbar.title = it?.title
})
//Toast.makeText(context, "Recipe Number: ${args.recipeIndex}",Toast.LENGTH_LONG).show()
setHasOptionsMenu(true)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.single_recipe_menu, menu)
viewModel.curRecipe.observe(viewLifecycleOwner, Observer {
val favIconDrawable: Int = if (it!!.favorite) R.drawable.ic_baseline_star_filled_24
else R.drawable.ic_baseline_star_border_24
menu.findItem(R.id.favorite).setIcon(favIconDrawable)
})
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.share -> viewModel.shareSuccess(this.requireActivity())
R.id.favorite -> viewModel.toggleFavorite()
}
return super.onOptionsItemSelected(item)
}
}
菜单布局如下:
<?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/share"
android:enabled="true"
android:icon="@drawable/ic_baseline_share_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/favorite"
android:enabled="true"
android:icon="@drawable/ic_baseline_star_border_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
</menu>
此片段由传入 recipeID 值的 NavigationUI 从另一个片段启动。我试过在这个片段的 onResume 中使用 setHasOptionsMenu(true) 但它没有效果。知道为什么 optionsMenu 不持久吗?
似乎在 MainActivity 的 onCreate()
方法中使用 setSupportActionBar(toolbar)
解决了 optionsMenu 不持久的问题。但是,这打破了我用来在片段 windows.
上显示标题的方法
工具栏属于 Activity,不属于片段。因此,当方向更改后重新创建视图时,工具栏将设置为应用程序标题。当片段首次加载时不会发生这种情况,因为标题是由片段的 onCreate()
设置的。因此,解决方案是将自定义标题移动到片段的 onResume()
,以便每次在屏幕上显示视图时重置它。
我正在像这样设置片段中的标题,因为如果我让导航控制器使用 navigation.xml 中的标签来设置标题,当片段加载到自定义工具栏布局的位置时,我会得到一个奇怪的行为正在被新的片段标题替换,并在右侧闪烁。
所以这个解决方案的 boiled-down 代码是:
片段:
class SingleRecipeFragment : Fragment() {
override fun onCreateView(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onResume() {
super.onResume()
/** This will reset your title every time the fragment is redrawn **/
(requireActivity() as MainActivity).toolbar.title = "Some Custom Title"
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.single_recipe_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.share -> someMethodYouWantToRun()
R.id.favorite -> someOtherMethod()
}
return super.onOptionsItemSelected(item)
}
}
在您的 Activity 的 onCreate()
中,调用:
setSupportActionBar(toolbar)
这是为选项菜单扩充的菜单布局资源文件(与问题中的内容没有变化):
<?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/share"
android:enabled="true"
android:icon="@drawable/ic_baseline_share_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/favorite"
android:enabled="true"
android:icon="@drawable/ic_baseline_star_border_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
</menu>
选项菜单中的图标工作正常,但当您通过旋转屏幕改变方向时,图标会消失。
class SingleRecipeFragment : Fragment() {
private lateinit var viewModel: SingleRecipeViewModel
private lateinit var viewModelFactory: SingleRecipeViewModelFactory
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentSingleRecipeBinding = DataBindingUtil.inflate(inflater,
R.layout.fragment_single_recipe, container, false)
val args =
SingleRecipeFragmentArgs.fromBundle(
requireArguments()
)
val application = requireNotNull(this.activity).application
viewModelFactory =
SingleRecipeViewModelFactory(
args.recipeIndex, application
)
viewModel = ViewModelProvider(this,viewModelFactory)
.get(SingleRecipeViewModel::class.java)
binding.singleRecipeViewModel = viewModel
binding.lifecycleOwner = this
viewModel.curRecipe.observe(viewLifecycleOwner, Observer {
(requireActivity() as MainActivity).toolbar.title = it?.title
})
//Toast.makeText(context, "Recipe Number: ${args.recipeIndex}",Toast.LENGTH_LONG).show()
setHasOptionsMenu(true)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.single_recipe_menu, menu)
viewModel.curRecipe.observe(viewLifecycleOwner, Observer {
val favIconDrawable: Int = if (it!!.favorite) R.drawable.ic_baseline_star_filled_24
else R.drawable.ic_baseline_star_border_24
menu.findItem(R.id.favorite).setIcon(favIconDrawable)
})
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.share -> viewModel.shareSuccess(this.requireActivity())
R.id.favorite -> viewModel.toggleFavorite()
}
return super.onOptionsItemSelected(item)
}
}
菜单布局如下:
<?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/share"
android:enabled="true"
android:icon="@drawable/ic_baseline_share_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/favorite"
android:enabled="true"
android:icon="@drawable/ic_baseline_star_border_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
</menu>
此片段由传入 recipeID 值的 NavigationUI 从另一个片段启动。我试过在这个片段的 onResume 中使用 setHasOptionsMenu(true) 但它没有效果。知道为什么 optionsMenu 不持久吗?
似乎在 MainActivity 的 onCreate()
方法中使用 setSupportActionBar(toolbar)
解决了 optionsMenu 不持久的问题。但是,这打破了我用来在片段 windows.
工具栏属于 Activity,不属于片段。因此,当方向更改后重新创建视图时,工具栏将设置为应用程序标题。当片段首次加载时不会发生这种情况,因为标题是由片段的 onCreate()
设置的。因此,解决方案是将自定义标题移动到片段的 onResume()
,以便每次在屏幕上显示视图时重置它。
我正在像这样设置片段中的标题,因为如果我让导航控制器使用 navigation.xml 中的标签来设置标题,当片段加载到自定义工具栏布局的位置时,我会得到一个奇怪的行为正在被新的片段标题替换,并在右侧闪烁。
所以这个解决方案的 boiled-down 代码是:
片段:
class SingleRecipeFragment : Fragment() {
override fun onCreateView(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onResume() {
super.onResume()
/** This will reset your title every time the fragment is redrawn **/
(requireActivity() as MainActivity).toolbar.title = "Some Custom Title"
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.single_recipe_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.share -> someMethodYouWantToRun()
R.id.favorite -> someOtherMethod()
}
return super.onOptionsItemSelected(item)
}
}
在您的 Activity 的 onCreate()
中,调用:
setSupportActionBar(toolbar)
这是为选项菜单扩充的菜单布局资源文件(与问题中的内容没有变化):
<?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/share"
android:enabled="true"
android:icon="@drawable/ic_baseline_share_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/favorite"
android:enabled="true"
android:icon="@drawable/ic_baseline_star_border_24"
android:title="Share"
android:visible="true"
app:showAsAction="ifRoom" />
</menu>