90

Is it possible to change the option menu items programmatically? Can anyone provide me with an example please?

Also, I want to disable certain items, so that they don't listen to the clicks, is it possible?

dbc
  • 104,963
  • 20
  • 228
  • 340
Farhan
  • 3,206
  • 14
  • 49
  • 62

12 Answers12

214

For anyone needs to change the options of the menu dynamically:

private Menu menu;

// ...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    this.menu = menu;
    getMenuInflater().inflate(R.menu.options, menu);
    return true;
}

// ...

private void hideOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(false);
}

private void showOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(true);
}

private void setOptionTitle(int id, String title)
{
    MenuItem item = menu.findItem(id);
    item.setTitle(title);
}

private void setOptionIcon(int id, int iconRes)
{
    MenuItem item = menu.findItem(id);
    item.setIcon(iconRes);
}
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 8
    One caveat is that you have to make sure that `menu` has been set before attempting to get a `MenuItem` out of it. For example, if you have something like `actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS)`, the tabs are loaded before the menu, so calling `hideOption`/`showOption` within `onTabSelected` results in a null pointer exception. – SaltyNuts Mar 26 '13 at 17:02
  • When I use `item.setVisible(false);`, the item only gets hidden when I click on the Menu itself. If I use `invalidateOptionsMenu();` the item do not respond to click. I appreciate if you could help me on a similar issue that I am facing. https://stackoverflow.com/questions/54756799/android-studio-invalidateoptionsmenu-causes-the-always-visible-items-to-stop – Aliton Oliveira Feb 18 '19 at 23:51
  • @AlitonOliveira you should put your item.setVisibility(false) part inside onCreateOptionsMenu method by by checking your flag variable status and you should change the bool value of your flag and invalidateOptionsMenu. it will work. – Kidus Tekeste Nov 10 '19 at 10:24
  • The documentation of `setVisible` states that you should also call `setEnabled(false)` otherwise the item can still be invoked via it's shortcut – Florian Walther Jun 21 '20 at 20:44
35

menu.xml

  <item 
    android:id="@+id/item1"
    android:title="your Item">
  </item>

put in your java file

  public void onPrepareOptionsMenu(Menu menu) {

    menu.removeItem(R.id.item1);
}
Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79
Imdad Sarkar
  • 1,245
  • 2
  • 12
  • 24
  • This is the one I was looking for because I want to make the decision once at runtime but do not need to change the options after. I used: @Override public boolean onPrepareOptionsMenu(Menu menu) { if (!showItemName) { menu.removeItem(R.id.itemname); } return true; } – notmystyle Sep 24 '17 at 23:44
20

Like Nikolay said do that in onPrepareOptionsMenu().

For menu items in the action bar you have to invalidate the menu with activity.invalidateOptionsMenu();

This is descriped in more detail here How can I refresh the ActionBar when onPrepareOptionsMenu switched menu entries?

Community
  • 1
  • 1
corban
  • 618
  • 6
  • 16
7

To disable certain items:

MenuItem item = menu.findItem(R.id.ID_ASSING_TO_THE_ITEM_IN_MENU_XML);
item.setEnabled(false);
Marcin S.
  • 11,161
  • 6
  • 50
  • 63
  • When I set `item.setVisible(false);`, my item only gets hidden when I click on the Menu itself (three dots). If I use `invalidateOptionsMenu();` some items do not respond to click. I appreciate if you could help me on a similar issue that I am facing. https://stackoverflow.com/questions/54756799/android-studio-invalidateoptionsmenu-causes-the-always-visible-items-to-stop – Aliton Oliveira Feb 18 '19 at 23:42
7

If I have to change the contents of my options menu I perform it during the onMenuOpened(). This allows me to check the running state at the very moment that the user is accessing the menu.

public boolean onMenuOpened(int featureid, Menu menu)
    {
        menu.clear();
        if (!editable)
        {
            MenuItem itemAdd = menu.add(0, REASSIGN, Menu.NONE, context.getString(R.string.reassign));
            MenuItem itemMod = menu.add(1, EDIT, Menu.NONE, context.getString(R.string.modify));
            MenuItem itemDel = menu.add(2, DELETE, Menu.NONE, context.getString(R.string.delete));
            itemAdd.setShortcut('0', 'a');
            itemMod.setShortcut('1', 'm');
            itemDel.setShortcut('2', 'd');
        }
        else
        {
            MenuItem itemSave = menu.add(3, SAVE, Menu.NONE, context.getString(R.string.savechanges));
            itemSave.setShortcut('0', 'S');
        }


        return true;
    }
Ashterothi
  • 3,282
  • 1
  • 21
  • 35
  • A few words of comment. onMenuOpened is called twice. First time menu var is null, second time menu var is prepared for using. I always use 'if' clause to check if menu var isn't null. – Ksiądz Pistolet Mar 06 '19 at 19:45
4

using the following lines i have done to add the values in menu

getActivity().invalidateOptionsMenu();

try this work like a charm to me.

S HemaNandhini
  • 333
  • 3
  • 5
3

Try this code:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu=menu;
    updateMenuItems(menu);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.document_list_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    if (item.getItemId() == android.R.id.home) {
        onHomeButtonPresssed();
    }else if (item.getItemId() == R.id.action_delete) {
        useCheckBoxAdapter=false;
        deleteDocuments();
    } else if (item.getItemId() == R.id.share) {
        useCheckBoxAdapter=false;
        shareDocuments();
    } else if (item.getItemId() == R.id.action_tick) {
        useCheckBoxAdapter=true;
        onShowCheckboxes();
    }
    updateMenuItems(menu);
    return true;
}

private void updateMenuItems(Menu menu){
    if (useCheckBoxAdapter && menu != null) {
        menu.findItem(R.id.action_delete).setVisible(true);
        menu.findItem(R.id.share).setVisible(true);
        menu.findItem(R.id.action_tick).setVisible(false);
    } else {
        menu.findItem(R.id.action_delete).setVisible(false);
        menu.findItem(R.id.share).setVisible(false);
        menu.findItem(R.id.action_tick).setVisible(true);
    }
    invalidateOptionsMenu();
}
Skywalker
  • 1,717
  • 1
  • 22
  • 25
  • When I use `invalidateOptionsMenu();`, my always visible items stop working (I mean the items do not respond to click). I appreciate if you could help me on a similar issue that I am facing. https://stackoverflow.com/questions/54756799/android-studio-invalidateoptionsmenu-causes-the-always-visible-items-to-stop – Aliton Oliveira Feb 18 '19 at 23:37
2

You can do something simple like I did. Just change the text to what is needed when the menu item is touched. I needed to turn the sound off and on, plus the ability to perform an action by touching it. Here is my code:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.audioOn:
        audioOn = !audioOn;
        if (audioOn)
            item.setTitle("Audio Off");
        else
            item.setTitle("Audio On");
        return true;

    case R.id.touchOn:
        touchOn = !touchOn;
        if (touchOn)
            item.setTitle("Touch Off");
        else
            item.setTitle("Touch On");
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

audioOn and touchOn are booleans checked in other parts of the code. Hope this helps.

bob
  • 688
  • 8
  • 15
  • How can I do this dynamically. I mean...calling a webservice on selecting an option item and then on its successful response...re-calling onCreateOptionsMenu. How to do so? – Narendra Singh Nov 12 '15 at 11:15
2

you can accomplish your task simply by implementing as below:

private Menu menu;

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.drive_menu, menu);
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu = menu;
    return super.onPrepareOptionsMenu(menu);
}

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

    if (id == R.id.action_toggle_grid) {
        handleMenuOption(id);
        return true;

    } else if(id == R.id.action_toggle_list){
        handleMenuOption(id);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void handleMenuOption(int id) {
    MenuItem item = menu.findItem(id);
    if (id == R.id.action_toggle_grid){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_list).setVisible(true);
    }else if (id == R.id.action_toggle_list){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_grid).setVisible(true);
    }
}
Chiranjhivi Ghimire
  • 1,739
  • 1
  • 19
  • 21
2
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.calendar, menu);
        if(show_list == true) {         

        if(!locale.equalsIgnoreCase("sk")) menu.findItem(R.id.action_cyclesn).setVisible(false);

        return true;
    }
Stefan Cizmar
  • 51
  • 1
  • 3
1

In case you have a BottomBar:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    if (mBottomBar.getCurrentTabId() == R.id.tab_more) {
        getMenuInflater().inflate(R.menu.more_menu, menu);
    }

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.preferences:
            startActivity(new Intent(this, PreferenceActivity.class));
            break;
    }

    return super.onOptionsItemSelected(item);
}

Then you just need to call:

@Override
public void onBottomBarClick(int tabId) {
    supportInvalidateOptionsMenu();
}
1

Kotlin Code for accessing toolbar OptionsMenu items programmatically & change the text/icon ,..:

1-We have our menu item in menu items file like: menu.xml, sample code for this:

 <?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/balance"
      android:title="0"
      android:orderInCategory="100"
      app:showAsAction="always" />
 </menu>

2- Define a variable for accessing menu object in class :

var menu: Menu? = null

3- initial it in onCreateOptionsMenu :

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    this.menu = menu
    return true
}

4- Access the menu items inside your code or fun :

private fun initialBalanceMenuItemOnToolbar() {
var menuItemBalance = menu?.findItem(R.id.balance)
    menuItemBalance?.title = Balance?.toString() ?: 0.toString()
    // for change icon : menuWalletBalance?.icon
}
Hamed Jaliliani
  • 2,789
  • 24
  • 31