我一直在关注invalidateOptionsMenu() ,我知道它的作用。 但是我想不出这个方法可能有用的任何现实生活中的例子。

我的意思是,例如,假设我们想要为ActionBar添加一个新的MenuItem ,我们可以从onCreateOptionsMenu(Menu menu)获取菜单,并在任何按钮的操作中使用它。

现在我真正的问题是,遵循使用invalidateOptionsMenu()的唯一方法?

bool _OtherMenu; protected override void OnCreate (Bundle bundle) { _OtherMenu = false; base.OnCreate (bundle); SetContentView (Resource.Layout.Main); Button button = FindViewById(Resource.Id.myButton); button.Click += delegate { if(_OtherMenu) _OtherMenu = false; else _OtherMenu = true; InvalidateOptionsMenu (); }; } public override bool OnCreateOptionsMenu (IMenu menu) { var inflater = this.SupportMenuInflater; if(_OtherMenu) inflater.Inflate (Resource.Menu.another_menu, menu); else inflater.Inflate (Resource.Menu.main_activity_menu, menu); return base.OnCreateOptionsMenu (menu); }

单击按钮,将出现另一个菜单。 再次单击该按钮,将出现上一个菜单。

PS对不起C#语法。

invalidateOptionsMenu()用于表示Android,菜单内容已更改,菜单应重新绘制。 例如,单击在运行时添加另一个菜单项的按钮,或隐藏菜单项组。 在这种情况下,您应该调用invalidateOptionsMenu() ,以便系统可以在UI上重绘它。 此方法是操作系统调用onPrepareOptionsMenu()的信号,您可以在其中实现必要的菜单操作。 此外, OnCreateOptionsMenu()在活动(片段)创建期间仅调用一次,因此此方法无法处理运行时菜单更改。

所有都可以在文档中find:

在系统调用onCreateOptionsMenu()之后,它会保留您填充的菜单的实例,并且不会再次调用onCreateOptionsMenu(),除非由于某种原因菜单失效。 但是,您应该仅使用onCreateOptionsMenu()来创建初始菜单状态,而不是在活动生命周期中进行更改。

如果要根据活动生命周期中发生的事件修改选项菜单,可以在onPrepareOptionsMenu()方法中执行此操作。 此方法会将Menu对象传递给当前存在,以便您可以对其进行修改,例如添加,删除或禁用项目。 (片段还提供onPrepareOptionsMenu()回调。)

在Android 2.3.x及更低版本中,每次用户打开选项菜单(按菜单按钮)时,系统都会调用onPrepareOptionsMenu()。

在Android 3.0及更高版本中,当操作栏中显示菜单项时,选项菜单被视为始终打开。 当事件发生并且您想要执行菜单更新时,必须调用invalidateOptionsMenu()以请求系统调用onPrepareOptionsMenu()。

使用此命令在应用程序生命周期中重新加载新菜单:

ActivityCompat.invalidateOptionsMenu(getActivity());

你需要重写onPrepareOptionsMenu()方法,用同样的方法编写动作菜单的更新代码,如果你使用的是片段,那么添加setHasOptionsMenu(true); 在onCreateView() 。

希望它能帮到你

我发现的一个用途是强制onResume和onCreateOptionsMenu/onPrepareOptionsMenu之间的操作顺序。 自然顺序(至少从平台22开始)似乎会翻转,特别是在重新定位设备时。

在onResume ()中调用invalidateOptionsMenu (),你将保证在onResume之后调用onPrepareOptionsMenu (之前可能另外调用它)。 例如,这将允许基于onResume检索的数据启用菜单项。

编辑:这是一个更好的答案问题。

对于invalidateOptionsMenu()一个很好的用途是当我们有一个ListView和Delete All MenuItem时,所以当ListView为空时我们应该使用invalidateOptionsMenu()来删除Delete All MenuItem 。

这是与此答案相关的问题: 问题 。

/** * Set a hint for whether this fragment's menu should be visible. This * is useful if you know that a fragment has been placed in your view * hierarchy so that the user can not currently seen it, so any menu items * it has should also not be shown. * * @param menuVisible The default is true, meaning the fragment's menu will * be shown as usual. If false, the user will not see the menu. */ public void setMenuVisibility(boolean menuVisible) { if (mMenuVisible != menuVisible) { mMenuVisible = menuVisible; if (mHasMenu && isAdded() && !isHidden()) { mHost.onSupportInvalidateOptionsMenu(); } } }

XML菜单示例:

示例片段中的代码:

private boolean isMenuItemChecked; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); setMenuVisibility(false); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.my_menu, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); try { menu.findItem(R.id.action_check).setVisible(!isMenuItemChecked); menu.findItem(R.id.action_uncheck).setVisible(isMenuItemChecked); } catch(Exception e) { Log.e(TAG, "onPrepareOptionsMenu error"); } } public void loadUi(boolean isMenuItemChecked) { this.isMenuItemChecked = isMenuItemChecked; setMenuVisibility(true); }

对我有用的最佳方式如下所示

将菜单的初始状态放在onCreateOptionsMenu(…)中

使用invalidateOptionsMenu()强制onCreateOptionsMenu(…)和onPrepareOptionsMenu(…)

在onPrepareOptionsMenu(…)中,调用menu.clear()从菜单中删除所有项目。

仍然在onPrepareOptionsMenu(…)中将动态菜单更改为清除后

希望这可以帮助…

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐