[android] Android: How to enable/disable option menu item on button click?

I can easily do it when I am using onCreateOptionsMenu or onOptionsItemSelected methods.

But I have a button somewhere in screen, and on clicking that button, it should enable/disable context menu items.

This question is related to android contextmenu menuitem

The answer is


If visible menu

menu.findItem(R.id.id_name).setVisible(true);

If hide menu

menu.findItem(R.id.id_name).setVisible(false);

simplify @Vikas version

@Override
public boolean onPrepareOptionsMenu (Menu menu) {

    menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
    return true;
}

Generally can change the properties of your views in runtime:

(Button) item = (Button) findViewById(R.id.idBut);

and then...

item.setVisibility(false)

but

if you want to modify de visibility of the options from the ContextMenu, on press your button, you can activate a flag, and then in onCreateContextMenu you can do something like this:

 @Override
        public void onCreateContextMenu(ContextMenu menu, 
                View v,ContextMenu.ContextMenuInfo menuInfo) {

            super.onCreateContextMenu(menu, v, menuInfo);

                menu.setHeaderTitle(R.string.context_title);

                if (flagIsOn()) {
                    addMenuItem(menu, "Option available", true);
                } else {
                    Toast.makeText(this, "Option not available", 500).show();
                }

        }

I hope this helps


A more modern answer for an old question:

MainActivity.kt

private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
    if (new != old) invalidateOptionsMenu()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_main_activity, menu)
    return super.onCreateOptionsMenu(menu)
}

override fun onPrepareOptionsMenu(menu: Menu): Boolean {
    menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
    return super.onPrepareOptionsMenu(menu)
}

menu_main_activity.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">
<item
    android:id="@+id/action_my_action"
    android:icon="@drawable/ic_my_icon_24dp"
    app:iconTint="@drawable/menu_item_icon_selector"
    android:title="My title"
    app:showAsAction="always" />
</menu>

menu_item_icon_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?enabledMenuIconColor" android:state_enabled="true" />
<item android:color="?disabledMenuIconColor" />

attrs.xml

<resources>   
    <attr name="enabledMenuIconColor" format="reference|color"/>
    <attr name="disabledMenuIconColor" format="reference|color"/>
</resources>

styles.xml or themes.xml

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="disabledMenuIconColor">@color/white_30_alpha</item>
    <item name="enabledMenuIconColor">@android:color/white</item>

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    // getMenuInflater().inflate(R.menu.home, menu);
    return false;
}

You could save the item as a variable when creating the option menu and then change its properties at will.

private MenuItem securedConnection;
private MenuItem insecuredConnection;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.connect_menu, menu);
    securedConnection = menu.getItem(0);
    insecuredConnection =  menu.getItem(1);
    return true;
}

public void foo(){
       securedConnection.setEnabled(true);
}    

What I did was save a reference to the Menu at onCreateOptionsMenu. This is similar to nir's answer except instead of saving each individual item, I saved the entire menu.

Declare a Menu Menu toolbarMenu;.

Then in onCreateOptionsMenusave the menu to your variable

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

Now you can access your menu and all of its items anytime you want. toolbarMenu.getItem(0).setEnabled(false);


On all android versions, easiest way: use this to SHOW a menu action icon as disabled AND make it FUNCTION as disabled as well:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

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

    if (myItemShouldBeEnabled) {
        item.setEnabled(true);
        item.getIcon().setAlpha(255);
    } else {
        // disabled
        item.setEnabled(false);
        item.getIcon().setAlpha(130);
    }
}

the best solution when you are perform on navigation drawer

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.setGroupVisible(0,false);
        return true;
    }

  @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

                case R.id.item_id:

                       //Your Code....

                        item.setEnabled(false);
                        break;
              }
            return super.onOptionsItemSelected(item);
     }

How to update the current menu in order to enable or disable the items when an AsyncTask is done.

In my use case I needed to disable my menu while my AsyncTask was loading data, then after loading all the data, I needed to enable all the menu again in order to let the user use it.

This prevented the app to let users click on menu items while data was loading.

First, I declare a state variable , if the variable is 0 the menu is shown, if that variable is 1 the menu is hidden.

private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.

Then in my onCreateOptionsMenu() I check for this variable , if it's 1 I disable all my items, if not, I just show them all

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);

        if(mMenuState==1){
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(false);
            }
        }else{
             for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(true);
            }
        }

        return super.onCreateOptionsMenu(menu);
    }

Now, when my Activity starts, onCreateOptionsMenu() will be called just once, and all my items will be gone because I set up the state for them at the start.

Then I create an AsyncTask Where I set that state variable to 0 in my onPostExecute()

This step is very important!

When you call invalidateOptionsMenu(); it will relaunch onCreateOptionsMenu();

So, after setting up my state to 0, I just redraw all the menu but this time with my variable on 0 , that said, all the menu will be shown after all the asynchronous process is done, and then my user can use the menu.

 public class LoadMyGroups extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration. 

        }

        @Override
        protected Void doInBackground(Void... voids) {
           //Background work

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
            invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu

        }
    }

Results

enter image description here


Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to contextmenu

How to add a "open git-bash here..." context menu to the windows explorer? Android: How to enable/disable option menu item on button click? How to add a custom right-click menu to a webpage? Making custom right-click context menus for my web-app Right click to select a row in a Datagridview and show a menu to delete it right click context menu for datagridview How do I create a right click context menu in Java Swing? How to disable right-click context-menu in JavaScript How to add "active" class to wp_nav_menu() current menu item (simple way) How do I hide a menu item in the actionbar? Handling a Menu Item Click Event - Android android: changing option menu items programmatically How to change menu item text dynamically in Android Sql Server 'Saving changes is not permitted' error ? Prevent saving changes that require table re-creation Android: How to enable/disable option menu item on button click? How to change the Text color of Menu item in Android? How do I center align horizontal <UL> menu?