367

我有一个带有菜单项的操作栏。如何隐藏/显示该菜单项?

这就是我想要做的:

MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
4

26 回答 26

518

获取MenuItem指向此类项目的指针,调用setVisible它以调整其可见性,然后调用invalidateOptionsMenu()您的活动,以便相应地调整 ActionBar 菜单。

更新: AMenuItem不是您布局中的常规视图。它有些特别,完全不同。您的代码返回nullitem导致崩溃。你需要做的是:

MenuItem item = menu.findItem(R.id.addAction);

这是您应该调用的顺序:首先调用invalidateOptionsMenu(),然后在内部onCreateOptionsMenu(Menu)获取对 MenuItem 的引用(通过调用menu.findItem())并调用setVisible()

于 2012-05-21T21:24:14.250 回答
177

找到这个问题的附录:

如果您想随时更改菜单项的可见性,您只需在活动中设置一个成员变量,以记住您要隐藏菜单并调用invalidateOptionsMenu()和隐藏您覆盖的onCreateOptionsMenu(...)方法中的项目。

//anywhere in your code
...
mState = HIDE_MENU; // setting state
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == HIDE_MENU)
    {
        for (int i = 0; i < menu.size(); i++)
            menu.getItem(i).setVisible(false);
    }
}

在我的示例中,我隐藏了所有项目。

于 2012-11-27T12:40:54.260 回答
94

是的。

  1. 您可以设置标志/条件。
  2. invalidateOptionsMenu()当您想隐藏选项时调用。这将调用onCreateOptionsMenu().
  3. onCreateOptionsMenu()中,检查标志/条件并按以下方式显示或隐藏它:
MenuItem item = menu.findItem(R.id.menu_Done);

if (flag/condition)) {
  item.setVisible(false); 
} else { }
于 2012-10-27T10:12:41.963 回答
39

你可以这样称呼:

MenuItem item = menu.findItem(R.id.my_item);
item.setVisible(false);

更新:

确保您的代码不会返回nullitem否则可能会使应用程序崩溃。

于 2012-05-21T21:24:38.193 回答
37

我正在寻找更多上下文的答案。现在我已经弄清楚了,我将添加该答案。

默认情况下在菜单 xml 中隐藏按钮

默认情况下,共享按钮将被隐藏,由 设置android:visible="false"

在此处输入图像描述

main_menu.xml

<?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">

    <!-- hide share button by default -->
    <item
        android:id="@+id/menu_action_share"
        android:icon="@drawable/ic_share_white_24dp"
        android:visible="false"     
        android:title="Share"
        app:showAsAction="always"/>

    <item
        android:id="@+id/menu_action_settings"
        android:icon="@drawable/ic_settings_white_24dp"
        android:title="Setting"
        app:showAsAction="ifRoom"/>

</menu>

在代码中显示按钮

但是可以根据某些条件选择显示共享按钮。

在此处输入图像描述

MainActivity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem shareItem = menu.findItem(R.id.menu_action_share);

    // show the button when some condition is true
    if (someCondition) {        
        shareItem.setVisible(true);
    }

    return true;
}

也可以看看

于 2016-09-05T06:27:43.250 回答
24

对我不起作用。我必须明确地使用onPrepareOptionsMenu来设置一个不可见的项目。

所以用于onCreateOptionsMenu创建菜单和onPrepareOptionsMenu更改可见性等。

于 2014-09-08T22:08:10.587 回答
10

最初在菜单布局文件中将菜单项可见性设置为 false,如下所示:

<?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:visible="false"
        android:id="@+id/action_do_something"
        android:title="@string/txt_do_something"
        app:showAsAction="always|withText"
        android:icon="@drawable/ic_done"/>
</menu>

然后,您可以在扩展菜单后在 onCreateOptionsMenu() 中简单地将菜单项的可见性设置为 false。

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(menu,R.menu.menu);
    MenuItem item = menu.findItem(R.id.menuItemId);
    if (item != null){
        item.setVisible(false);
    }
}
于 2013-11-14T10:27:05.053 回答
10

尝试这个:

MenuItem myitem = menu.findItem(R.id.my_item);
myitem.setVisible(false);
于 2019-02-16T10:48:44.687 回答
8

这对 Activity 和 Fragment 都有效

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    if (menu.findItem(R.id.action_messages) != null)
        menu.findItem(R.id.action_messages).setVisible(false);
}
于 2015-07-15T11:15:20.193 回答
7

P1r4nh4 答案工作正常,我只是使用布尔标志简化了它:

public int mState = 0; //at the top of the code
//where you want to trigger the hide action
mState = 1; // to hide or mState = 0; to show
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == 1) //1 is true, 0 is false
    {
        //hide only option 2
            menu.getItem(2).setVisible(false);
    }
}
于 2013-04-13T19:11:04.257 回答
6

根据 Android 开发者官方网站,不建议在运行时更改菜单项或图标、可见性..等时使用 OnCreateOptionMenu(Menu menu)。

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

如果要根据活动生命周期中发生的事件修改选项菜单,可以在 onPrepareOptionsMenu() 方法中进行。此方法向您传递当前存在的 Menu 对象,以便您可以对其进行修改,例如添加、删除或禁用项目。(Fragments 还提供了一个 onPrepareOptionsMenu() 回调。) --AndroidDeveloper 官网 --

作为推荐您可以使用此onOptionsItemSelected(MenuItem item)方法跟踪用户输入。

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.edit) {
        Intent intent = new Intent(this, ExampleActivity.class);
        intent.putExtra(BUNDLE_KEY, mConnection);
        startActivityForResult(intent, PICK_CHANGE_REQUEST);
        return true;
    } else if (id == R.id.delete) {
        showDialog(this);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

如果您需要在运行时更改菜单项,您可以使用onPrepareOptionsMenu(Menu menu)来更改它们

@Override
public boolean onPrepareOptionsMenu(Menu menu){

    if (Utils.checkNetworkStatus(ExampleActivity.this)) {
        menu.findItem(R.id.edit).setVisible(true);
        menu.findItem(R.id.delete).setVisible(true);
    }else {
        menu.findItem(R.id.edit).setVisible(false);
        menu.findItem(R.id.delete).setVisible(false);
    }
    return true;
} 
于 2017-09-30T15:55:32.933 回答
5

您可以使用toolbar.getMenu().clear();一次隐藏所有菜单项

于 2016-11-24T05:47:57.877 回答
4

仅用一个命令隐藏菜单中所有项目的最佳方法是在菜单 xml 上使用“组”。只需在同一组内添加将在溢出菜单中的所有菜单项。

在此示例中,我们有两个将始终显示的菜单项(常规项和搜索)和三个溢出项:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/someItemNotToHide1"
        android:title="ITEM"
        app:showAsAction="always" />

    <item
        android:id="@+id/someItemNotToHide2"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:title="Search"/>

    <group android:id="@+id/overFlowItemsToHide">
    <item android:id="@+id/someID" 
    android:orderInCategory="1" app:showAsAction="never" />
    <item android:id="@+id/someID2" 
    android:orderInCategory="1" app:showAsAction="never" />
    <item android:id="@+id/someID3" 
    android:orderInCategory="1" app:showAsAction="never" />
    </group>
</menu>

然后,在您的活动上(最好在 onCreateOptionsMenu 上),使用命令 setGroupVisible 将所有菜单项的可见性设置为 false 或 true。

public boolean onCreateOptionsMenu(Menu menu) {
   menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}

如果您想在活动的其他任何地方使用此命令,请确保将菜单类保存到本地,并始终检查菜单是否为空,因为您可以在 createOptionsMenu 之前执行:

Menu menu;

public boolean onCreateOptionsMenu(Menu menu) {
       this.menu = menu;

}

public void hideMenus() {
       if (menu != null) menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible       
}
于 2017-06-11T23:01:03.380 回答
4

通过设置菜单中所有项目的可见性,应用栏菜单或溢出菜单将自动隐藏

例子

private Menu menu_change_language;

...

...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    ...
    ...
    menu_change_language = menu;
    menu_change_language.findItem(R.id.menu_change_language)
           .setVisible(true);

    return super.onCreateOptionsMenu(menu);
}

在转到其他片段之前,请使用以下代码:

if(menu_change_language != null){                 
    menu_change_language.findItem(R.id.menu_change_language)
       .setVisible(false);
}
于 2018-03-26T08:10:32.470 回答
3

https://stackoverflow.com/a/21215280/466363 - Look Alterno 和 Sufian 回答

  • ActivityCompat.invalidateOptionsMenu() 不回调 onPrepareOptionsMenu(); 它只是直接更新菜单。
  • 我的 someMethod() 从几个地方被调用,甚至在 onCreateOptionsMenu() 之前,所以我必须检查 mMenu != null。
  • 应该使用 API 8

.

private Menu mMenu;
   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
       inflater.inflate(R.menu.track_fragment, menu);
       mMenu = menu;
       }
   ...
   private void someMethod() {
   ...
       if (mMenu != null) {
          MenuItem item = mMenu.findItem(R.id.new_track);
          if (item != null) {
               item.setVisible(false);
               ActivityCompat.invalidateOptionsMenu(this.getActivity());
           }
       }
   ...
   }
  • ActivityCompat.invalidateOptionsMenu() 不回调 onPrepareOptionsMenu(); 它只是直接更新菜单。

  • 我的 someMethod() 从几个地方被调用,甚至在 onCreateOptionsMenu() 之前,所以我必须检查 mMenu != null。

  • 应该使用 API 8
于 2015-01-25T12:35:45.737 回答
3

为变量设置一个值并调用 invalidateOptionsMenu();

例如

    selectedid=arg2;
            invalidateOptionsMenu();


 public boolean onPrepareOptionsMenu(Menu menu) {

    if(selectedid==1){
        menu.findItem(R.id.action_setting).setVisible(false);
        menu.findItem(R.id.action_s2).setVisible(false);
        menu.findItem(R.id.action_s3).setVisible(false);
    }
    else{
        if(selectedid==2){
            menu.findItem(R.id.action_search).setVisible(false);
            menu.findItem(R.id.action_s4).setVisible(false);
            menu.findItem(R.id.action_s5).setVisible(false);
        }
    }
    return super.onPrepareOptionsMenu(menu);
}
于 2014-11-20T11:52:32.387 回答
3

Android kotlin,以编程方式隐藏或设置操作栏中菜单项的可见性。

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater = menuInflater
    inflater.inflate(R.menu.main_menu, menu)
    val method = menu.findItem(R.id.menu_method)
    method.isVisible = false //if want to show set true
    return super.onCreateOptionsMenu(menu)
}
于 2020-06-12T21:49:14.543 回答
3

如果您按照上述答案进行了所有操作,但菜单项仍然可见,请检查您是否引用了唯一资源。例如,在 onCreateOptionsMenu 或 onPrepareOptionsMenu

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    MenuItem menuOpen = menu.findItem(R.id.menu_open);
    menuOpen.setVisible(false);
}

Ctrl+单击 R.id.menu_open 并检查它是否仅存在于一个菜单文件中。如果此资源已在任何地方使用并加载到活动中,它将尝试隐藏在那里。

于 2017-03-03T18:22:14.180 回答
1

对于那些使用 Appcompat 库的人:如果您的 Activity 是 ActionBarActivity 的子类,您可以调用 supportInvalidateOptionsMenu()

在这里看到: https ://stackoverflow.com/a/19649877/1562524

于 2015-04-03T05:29:32.307 回答
1

我认为更好的方法是为菜单使用成员变量,在 onCreateOptionsMenu() 中对其进行初始化,然后只使用 setVisible() ,而不会使选项菜单无效。

于 2017-04-11T10:39:27.110 回答
1

您正在尝试从无法访问范围的活动中访问菜单项。查找菜单项的调用将返回null,因为视图既未与活动绑定,也未与您调用的布局绑定。

菜单项与诸如“导航栏”之类的项绑定,这些项又与相应的活动绑定。

因此在activity() 中初始化这些视图,然后使用该视图访问菜单项。

Navigation navView;
navView = findViewById(R.id.navigationView);

MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.setVisible(false);
于 2019-03-23T07:05:07.727 回答
1

这对我有用;我希望它可以帮助你:

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    getMenuInflater().inflate(R.menu.my_menu_setting, menu);

    for (int i = 0; i < menu.size(); i++){
        if(menu.getItem(i).getItemId() == R.id.this_item_i_want_to_hide){
            menu.getItem(i).setVisible(false);
        }
    }

    return true;
}
于 2021-05-07T17:45:05.230 回答
1

利用invalidateOptionsMenu()

为了打电话onPrepareOptionsMenu(menu: Menu?)

您应该仅使用 onCreateOptionsMenu() 来创建初始菜单状态,而不是在活动生命周期中进行更改...

当事件发生并且您想要执行菜单更新时,您必须调用 invalidateOptionsMenu() 来请求系统调用 onPrepareOptionsMenu()。

https://developer.android.com/guide/topics/ui/menus

于 2019-06-30T08:38:29.813 回答
1

这段代码对我有用

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu,menu);
    if (Application.sharedPreferences.getInt("type",1) == 2)
    {
        menuItem = menu.findItem(R.id.menu_travel_orders);
        menuItem.setVisible(false);
    }
    return super.onCreateOptionsMenu(menu);
}
于 2017-11-30T16:37:01.183 回答
1

这种方法对我有用:

private  Menu thismenu;

if (condition)
{
   if(thismenu != null)
   {
       thismenu.findItem(R.id.menu_save).setVisible(true);
       Toast.makeText(ProfileActivity.this, 
    ""+thismenu.findItem(R.id.menu_save).getTitle(),
                Toast.LENGTH_SHORT).show();
   }else
   {
       thismenu.findItem(R.id.menu_save).setVisible(false);
   }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   getMenuInflater().inflate(R.menu.profile_menu, menu);
   thismenu = menu;

   return true;
}
于 2018-07-22T00:55:11.630 回答
0

以正常方式创建菜单选项,请参见下面的代码,并在类中添加全局引用到菜单

Menu mMenu;  // global reference within the class
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_tcktdetails, menu);
    mMenu=menu;  // assign the menu to the new menu item you just created 
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_cancelticket) {
        cancelTicket();

        return true;
    }

    return super.onOptionsItemSelected(item);
}

现在,您可以通过使用按钮或在函数内运行此代码来切换菜单

if(mMenu != null) {
                mMenu.findItem(R.id.action_cancelticket).setVisible(false);
            }
于 2020-12-26T20:20:00.150 回答