如何更改 Android 上选项菜单上的 MenuItem?
Posted
技术标签:
【中文标题】如何更改 Android 上选项菜单上的 MenuItem?【英文标题】:How can I alter a MenuItem on the Options Menu on Android? 【发布时间】:2011-05-11 03:05:48 【问题描述】:我的Activity
上有一个带有MenuItem
“开始”的选项菜单。 When this MenuItem
is selected I would like to alter the Menu so it contains a MenuItem
"Stop".最后选择“停止”时,我想改变回“开始”。
这是我的部分代码不起作用。我在mymenu.xml
中列出了“开始”和“停止”我应该在创建菜单时删除“停止”:
public class MyActivity extends Activity
private boolean isStarted = false;
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inflater = getMenuInflater();
menu.removeItem(R.id.stop);
inflater.inflate(R.menu.mymenu, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case R.id.start:
isStarted = true;
return true;
case R.id.stop:
isStarted = false;
return true;
default:
return super.onOptionsItemSelected(item);
@Override
public boolean onPrepareOptionsMenu(Menu menu)
if(isStarted)
menu.removeItem(R.id.start);
menu.add(R.id.stop);
else
menu.removeItem(R.id.stop);
menu.add(R.id.start);
return true;
【问题讨论】:
您是否已经尝试在创建菜单时删除停止?代码看起来不错。我找不到任何会导致其他问题的东西。 @Octavian:我在getMenuInflater();
之后尝试了menu.removeItem(R.id.stop);
,但没有成功。我要么得到两个菜单项,一个“开始”,一个“假”(应该是“停止”),或者当我应该显示时菜单崩溃。
你想在哪里打电话给removeItem()
?在onPrepareOptionsMenu()
?
@Octavian:我第一次删除了onCreateOptionsMenu()
中的“停止”项目,然后我更改了onPrepareOptionsMenu()
中的项目。我现在将此添加到问题中的代码中。
【参考方案1】:
在 android 3.0 及更高版本上,您应该调用 invalidateOptionsMenu() 来请求系统调用 onPrepareOptionsMenu()。然后您可以修改方法中的选项菜单。您可以在此处https://developer.android.com/guide/topics/ui/menus#options-menu 查看 Android 文档的 Changing menu items at runtime 部分以了解更多详细信息。
【讨论】:
【参考方案2】:Flygenring 答案是正确的,但 menu.findItem() 滞后,并且在 onPrepareOptionsMenu(Menu menu) 中调用它会产生糟糕的用户体验.最好在创建菜单时获取一次 MenuItem 对象,然后每次屏幕上出现菜单时调用 setVisible:
MenuItem mDynamicMenuItem;
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
// Get dynamic menu item
mDynamicMenuItem = menu.findItem(R.id.menu_item);
return true;
// Prepare the Screen's standard options menu to be displayed. This is called right
// before the menu is shown, every time it is shown. You can use this method to
// efficiently enable/disable items or otherwise dynamically modify the contents.
@Override
public boolean onPrepareOptionsMenu(Menu menu)
super.onPrepareOptionsMenu(menu);
// Here is just a good place to update item
mDynamicMenuItem.setVisible(isVisible);
return true;
【讨论】:
此方法在菜单中只有一项时不起作用。【参考方案3】:感谢这篇文章中的信息,因为它解决了我菜单中错误标签的问题。我确实不得不稍微修改它并让最终代码运行良好,希望它可以为其他人节省一些时间和挫败感。它的解决方案略有不同,但我所做的主要更改是将 .setVisible 更改为 True 或 False,除了 i.shadrins 解决方案最适合我的需求。
@Override
public boolean onPrepareOptionsMenu(Menu menu)
super.onPrepareOptionsMenu(menu);
if(loggedIn)
logIn.setVisible(false);
logOut.setVisible(true);
else
logIn.setVisible(true);
logOut.setVisible(false);
return true;
@Override
public boolean onCreateOptionsMenu(Menu menu)
super.onCreateOptionsMenu(menu);
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
logIn = menu.findItem(R.id.loggedOut);
logOut = menu.findItem(R.id.loggedIn);
return true;
【讨论】:
应该放在哪个文件中?【参考方案4】:对于这种类型的操作,我通常选择不改变菜单项,而只是隐藏你不需要的:
@Override
public boolean onPrepareOptionsMenu(Menu menu)
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.start).setVisible(!isStarted);
menu.findItem(R.id.stop).setVisible(isStarted);
return true;
【讨论】:
刚刚看到我忘记按照前面的建议调用超类,并在docs 和source 中指定 只是为了更新,源代码可以在grepcode.com/file/repository.grepcode.com/java/ext/…找到【参考方案5】:我得到了解决方案。调用removeItem()
时,您基本上是在删除MenuItem
,因此也删除了引用。使用此代码有效。
private boolean isStarted = false;
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case 1:
isStarted = true;
return true;
case 0:
isStarted = false;
return true;
default:
return super.onOptionsItemSelected(item);
@Override
public boolean onPrepareOptionsMenu(Menu menu)
if(isStarted)
menu.removeItem(1);
menu.add(0, 0, 0, "Stop");
else
menu.removeItem(0);
menu.add(0, 1, 0, "Start");
return super.onPrepareOptionsMenu(menu);
您必须再次创建MenuItem
。这也是false
标签的原因。实际上,您不需要 MenuInflater
,因为您通过代码创建 Menu
,因此也不需要任何菜单 XML 文件。
【讨论】:
【参考方案6】:您可能需要在完成更改后调用 super.onPrepareOptionsMenu。来自docs:
派生类应该总是调用 一直到基类 实施。
【讨论】:
以上是关于如何更改 Android 上选项菜单上的 MenuItem?的主要内容,如果未能解决你的问题,请参考以下文章