How do I hide a menu item in the actionbar?
Asked Answered
M

27

375

I have an action bar with a menuitem. How can I hide/show that menu item?

This is what I'm trying to do:

MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
Machicolate answered 21/5, 2012 at 21:18 Comment(0)
E
528

Get a MenuItem pointing to such item, call setVisible on it to adjust its visibility and then call invalidateOptionsMenu() on your activity so the ActionBar menu is adjusted accordingly.

Update: A MenuItem is not a regular view that's part of your layout. Its something special, completely different. Your code returns null for item and that's causing the crash. What you need instead is to do:

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

Here is the sequence in which you should call: first call invalidateOptionsMenu() and then inside onCreateOptionsMenu(Menu) obtain a reference to the MenuItem (by calling menu.findItem()) and call setVisible() on it

Enthusiasm answered 21/5, 2012 at 21:24 Comment(13)
This is what I've thought of initially, but this crashes the application.Noll
@Stir Zoltán: Well that's how you do it, you may be doing it wrong if it crashes the application. For instance, your MenuItem may be null because you are using getItem instead of findItem. We could never know, without seeing both your code and crash log.Enthusiasm
OK but how can I get a reference to the menu outside the onCreateOptionsMenu method?Noll
@Stir Zoltán: Why would you want to do it outside onCreateOptionsMenu?Enthusiasm
Let's say I have a screen on which an "Add item" makes sense. On the "Add item" screen I don't wan't to have the "add item" menuitem enabled/visible.Noll
@Stir Zoltán: I believe you make no sense with that last comment... Simply get a reference to your menu item at onCreateOptionsMenu, and set the item visibility at that point. Or keep the reference around until you decide whether it should be visible or not.Enthusiasm
I think that (at best) this answer is poorly worded because the sequence of steps is wrong. The correct sequence is to first call invalidateOptionsMenu() and then inside onCreateOptionsMenu(Menu) obtain a reference to the MenuItem (by calling menu.findItem()) and call setVisible() on it. The answers by suhas_sm and by P1r4nh4 present the correct approach.Libava
If setTitle() is called after this, then the menu will appear again. So I think <https://mcmap.net/q/92126/-how-do-i-hide-a-menu-item-in-the-actionbar> is the best answerQuitrent
@TedHopp i wish you would add that info from comment to answer, insteadJudon
invalidateOptionsMenu() in onCreate()Tamqrah
i tried below and initially it would work and hid ethe item but as soon as you select another menu item it appears againAllpowerful
onPrepareOptionsMenu() should be used for show/hide logic instead of onCreateOptionsMenu() as it is only called once so not useful if you want to change the menu items after its initialization. So inflate in onCreate, but show/hide in onPrepare.Ambriz
If you working with fragments don't forget to add "setHasOptionsMenu(true)" in "onCreateView()" method in order to modify MenuItemsSaberio
V
183

Found an addendum to this question:

If you want to change the visibility of your menu items on the go you just need to set a member variable in your activity to remember that you want to hide the menu and call invalidateOptionsMenu() and hide the items in your overridden onCreateOptionsMenu(...) method.

//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);
    }
}

In my example I've hidden all items.

Verbenia answered 27/11, 2012 at 12:40 Comment(5)
This is exactly what I've been looking for. holding onto the MenuItem and calling setVisible() didn't seem to do what I expected (maybe because I was calling invalidateOptionsMenu() after, thus rebuilding the menu), but either way -- this works exactly as I was hoping, thanks!Lubet
If you're going to hide every item, there's an easier way. Instead of looping through each item here, you could just do: if (HIDE_MENU) { return false; } else { getSupportMenuInflater().inflate(R.menu.menu_settings, menu); return true; } The docs state: "You must return true for the menu to be displayed; if you return false it will not be shown".Michail
Also, I'd like to mention that this approach is much cleaner than the accepted answer. Thanks for sharing!Michail
by calling invalidateOptionMenu() onCreateOptionMenu() called and I handle my conditions in onCreateOptionMenu(). Thanks for good answerJemina
onPrepareOptionsMenu() should be used for show/hide logic instead of onCreateOptionsMenu() as it is only called once so not useful if you want to change the menu items after its initialization. So inflate in onCreate, but show/hide in onPrepare.Ambriz
M
97

Yes.

  1. You can set a flag/condition.
  2. Call invalidateOptionsMenu() when you want to hide the option. This will call onCreateOptionsMenu().
  3. In onCreateOptionsMenu(), check for the flag/condition and show or hide it the following way:
MenuItem item = menu.findItem(R.id.menu_Done);

if (flag/condition)) {
  item.setVisible(false); 
} else { }
Matisse answered 27/10, 2012 at 10:12 Comment(5)
Shouldn't it be invalidateOptionsMenu instead of invalidateOptions?Reckon
If you make your flag a boolean you can just set the item's visibility to the flag (or !flag) if need be. So, item.setVisbility(!flag); makes this a one liner with no if condition.Bemused
where is the variable "menu" defined?Allpowerful
It's passed as a parameter to onCreateOptionsMenuMatisse
using this method will mean the item still consumes space and you may end up with a "gap" in your UI where the button should be. Using removeItem in onPrepareOptionsMenu() will do the trick.Ambriz
A
45

I was looking for an answer with a little more context. Now that I have figured it out, I will add that answer.

Hide button by default in menu xml

By default the share button will be hidden, as set by android:visible="false".

enter image description here

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>

Show button in code

But the share button can optionally be shown based on some condition.

enter image description here

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;
}

See also

Apathy answered 5/9, 2016 at 6:27 Comment(1)
onPrepareOptionsMenu() should be used for show/hide logic instead of onCreateOptionsMenu() as it is only called once so not useful if you want to change the menu items after its initialization. So inflate in onCreate, but show/hide in onPrepare, then use invalidateOptionsMenu() to refresh the menu.Ambriz
U
40

You can call this:

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

Update:

Make sure your code doesn't returns null for item or it may crash the application.

Utilitarianism answered 21/5, 2012 at 21:24 Comment(1)
using this method will mean the item still consumes space and you may end up with a "gap" in your UI where the button should be. Using removeItem in onPrepareOptionsMenu() will do the trick.Ambriz
L
24

didn't work for me. I had to explicitly use onPrepareOptionsMenu to set an item invisible.

So use onCreateOptionsMenu to create the menu and onPrepareOptionsMenu to change visibility etc.

Linnie answered 8/9, 2014 at 22:8 Comment(2)
For me it worked both ways, but based on Android's docs onPrepareOptionsMenu seems like the right place to do this type of operation: "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."Surveyor
Yes, this is ideal. onPrepareOptionsMenu() should be used for show/hide logic instead of onCreateOptionsMenu() as it is only called once so not useful if you want to change the menu items after its initialization. So inflate in onCreate, but show/hide in onPrepare, then use invalidateOptionsMenu() to refresh the menu.Ambriz
R
11

Initially set the menu item visibility to false in the menu layout file as follows :

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

You can then simply set the visibility of the menu item to false in your onCreateOptionsMenu() after inflating the menu.

@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);
    }
}
Revenge answered 14/11, 2013 at 10:27 Comment(1)
onCreateOptionsMenu does not return a boolean value. The solution worked perfectly though.Kieger
T
10

Try this:

MenuItem myitem = menu.findItem(R.id.my_item);
myitem.setVisible(false);
Tuantuareg answered 16/2, 2019 at 10:48 Comment(0)
U
9

This worked for me from both Activity and 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);
}
Undenominational answered 15/7, 2015 at 11:15 Comment(1)
In my case onPrepareOptionsMenu returns boolean, not void.Rabbi
M
8

The best way to hide all items in a menu with just one command is to use "group" on your menu xml. Just add all menu items that will be in your overflow menu inside the same group.

In this example we have two menu items that will always show (regular item and search) and three overflow items:

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

Then, on your activity (preferable at onCreateOptionsMenu), use command setGroupVisible to set all menu items visibility to false or true.

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

If you want to use this command anywhere else on your activity, be sure to save menu class to local, and always check if menu is null, because you can execute before 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       
}
Marlin answered 11/6, 2017 at 23:1 Comment(0)
U
7

P1r4nh4 answer works fine, I just simplified it using a boolean flag:

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);
    }
}
Uriniferous answered 13/4, 2013 at 19:11 Comment(2)
Using 0 and 1 is not a "boolean flag", it's pseudo-boolean. besides, there is no reason to use an actual boolean here.Rickety
Also, you could have several states, not just one to hide and one to show. Depending on the complexity of your app and your refusal to write new activities for new app states you might have a SHOW_ALL state, a HIDE_ALL state, but also a HIDE_EDIT or HIDE_SHARE state in case you want to hide certain parts of your menu.Verbenia
R
7

According to Android Developer Official site,OnCreateOptionMenu(Menu menu) is not recomended for changing menu items or icons, visibility..etc at Runtime.

After the system calls onCreateOptionsMenu(), it retains an instance of the Menu you populate and will not call onCreateOptionsMenu() again unless the menu is invalidated for some reason. However, you should use onCreateOptionsMenu() only to create the initial menu state and not to make changes during the activity lifecycle.

If you want to modify the options menu based on events that occur during the activity lifecycle, you can do so in the onPrepareOptionsMenu() method. This method passes you the Menu object as it currently exists so you can modify it, such as add, remove, or disable items. (Fragments also provide an onPrepareOptionsMenu() callback.) --AndroidDeveloper Official Site --

As Recomended You can use this onOptionsItemSelected(MenuItem item) method track user inputs.

@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);
}

If you need to change Menu Items at Run time, You can use onPrepareOptionsMenu(Menu menu) to change them

@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;
} 
Rachitis answered 30/9, 2017 at 15:55 Comment(1)
some items are always visible, so when I setVisible(false) for the always visible item, it does not disappear until I click on the three dots (Menu itself). If I use invalidateOptionsMenu() in onPrepareOptionsMenu the items immediately reorganize itself, but they loose their actions (if I click on any item, it does nothing).Turkmen
U
5

You can use toolbar.getMenu().clear(); to hide all the menu items at once

Upbow answered 24/11, 2016 at 5:47 Comment(2)
@Ajeet_Yadav is there a way to make the menu visible after you clear it?Afflictive
call toolbar.inflateMenu(R.menu.main) to inflate the menu backFerromagnetic
R
4

https://mcmap.net/q/93312/-android-invalidateoptionsmenu-for-api-lt-11 - answered by Look Alterno and Sufian

  • ActivityCompat.invalidateOptionsMenu() doesn't callback onPrepareOptionsMenu(); it just update the menu directly.
  • My someMethod() get called from several places, even before onCreateOptionsMenu(), so I must check mMenu != null.
  • should work using 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() doesn't callback onPrepareOptionsMenu(); it just update the menu directly.

  • My someMethod() get called from several places, even before onCreateOptionsMenu(), so I must check mMenu != null.

  • should work using API 8
Ramiform answered 25/1, 2015 at 12:35 Comment(0)
U
4

By setting the Visibility of all items in Menu, the appbar menu or overflow menu will be Hide automatically

Example

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);
}

Before going to other fragment use bellow code:

if(menu_change_language != null){                 
    menu_change_language.findItem(R.id.menu_change_language)
       .setVisible(false);
}
Unconstitutional answered 26/3, 2018 at 8:10 Comment(0)
M
3

set a value to a variable and call invalidateOptionsMenu();

for example

    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);
}
Maxma answered 20/11, 2014 at 11:52 Comment(1)
some items are always visible, so when I setVisible(false) for the always visible item, it does not disappear until I click on the three dots (Menu itself). If I use invalidateOptionsMenu() in onPrepareOptionsMenu the items immediately reorganize itself, but they loose their actions (if I click on any item, it does nothing).Turkmen
R
3

If you did everything as in above answers, but a menu item is still visible, check that you reference to the unique resource. For instance, in onCreateOptionsMenu or onPrepareOptionsMenu

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

Ctrl+Click R.id.menu_open and check that it exists only in one menu file. In case when this resource is already used anywhere and loaded in an activity, it will try to hide there.

Rabbi answered 3/3, 2017 at 18:22 Comment(0)
A
3

Android kotlin, hide or set visibility of a menu item in the action bar programmatically.

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)
}
Antirachitic answered 12/6, 2020 at 21:49 Comment(0)
U
2

use invalidateOptionsMenu()

in order to call onPrepareOptionsMenu(menu: Menu?)

you should use onCreateOptionsMenu() only to create the initial menu state and not to make changes during the activity lifecycle...

When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().

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

Unnamed answered 30/6, 2019 at 8:38 Comment(0)
R
1

For those using the Appcompat library: If your Activity subclasses ActionBarActivity, you can call supportInvalidateOptionsMenu()

Seen here: https://mcmap.net/q/93313/-how-can-i-refresh-the-actionbar-when-onprepareoptionsmenu-switched-menu-entries

Remotion answered 3/4, 2015 at 5:29 Comment(0)
C
1

I think a better approach would be to use a member variable for the menu, initialize it in onCreateOptionsMenu() and just use setVisible() afterwards, without invalidating the options menu.

Cembalo answered 11/4, 2017 at 10:39 Comment(0)
D
1

this code worked for me

@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);
}
Dorotheadorothee answered 30/11, 2017 at 16:37 Comment(0)
O
1

This Approach worked for me:

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;
}
Omidyar answered 22/7, 2018 at 0:55 Comment(0)
S
1

You are trying to access a menu item from an activity, which dont have the access to scope. The call to find the menu item will return null, because the view is not binded with neither the activity nor the layout you are calling from.

The menu items are binded with items such as "Navigation Bar" which in turn are binded with the corresponding activity.

So initialize those views in activity (), and then access the menu items withing that views.

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

MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.setVisible(false);
Selfsustaining answered 23/3, 2019 at 7:5 Comment(0)
B
1

this works for me; I hope it helps you:

@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;
}
Barsky answered 7/5, 2021 at 17:45 Comment(0)
N
0

Create you menu options the normal way see code below and add a global reference within the class to the menu

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);
}

Now you can toggle your menu by running this code with a button or within a function

if(mMenu != null) {
                mMenu.findItem(R.id.action_cancelticket).setVisible(false);
            }
Ningpo answered 26/12, 2020 at 20:20 Comment(0)
A
0

If you're using material toolbar then use this

 var topMainToolbar = findViewById(R.id.myMaterialToolbar)
 val menuItem:MenuItem = topMainToolbar.menu.findItem(R.id.yourmenuItemId)
 menuItem.setVisible(false)
Adherence answered 26/10, 2023 at 4:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.