android: changing option menu items programmatically
Asked Answered
N

12

91

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?

Natatorial answered 20/8, 2011 at 16:36 Comment(0)
D
215

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);
}
Dispense answered 28/7, 2012 at 9:44 Comment(4)
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.Subscapular
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. #54757299Roasting
@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.Hypogenous
The documentation of setVisible states that you should also call setEnabled(false) otherwise the item can still be invoked via it's shortcutAtherton
J
34

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);
}
Jackofalltrades answered 20/8, 2011 at 17:33 Comment(1)
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; }Crawfish
B
21

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?

Batchelder answered 14/11, 2012 at 23:7 Comment(0)
B
7

To disable certain items:

MenuItem item = menu.findItem(R.id.ID_ASSING_TO_THE_ITEM_IN_MENU_XML);
item.setEnabled(false);
Blaubok answered 28/1, 2013 at 4:20 Comment(1)
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. #54757299Roasting
N
6

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;
    }
Nobe answered 20/8, 2011 at 17:38 Comment(1)
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.Sining
A
4

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

getActivity().invalidateOptionsMenu();

try this work like a charm to me.

Aurthur answered 25/11, 2016 at 11:34 Comment(0)
M
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();
}
Matthew answered 30/12, 2015 at 6:19 Comment(1)
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. #54757299Roasting
A
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.

Algernon answered 30/10, 2013 at 19:46 Comment(1)
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?Time
R
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);
    }
}
Rahal answered 23/8, 2016 at 6:54 Comment(0)
H
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;
    }
Hanafee answered 5/4, 2019 at 10:22 Comment(0)
S
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();
}
Scorpaenoid answered 14/4, 2017 at 19:13 Comment(0)
K
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
}
Klutz answered 12/12, 2018 at 15:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.