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

AndroidContextmenuMenuitem

Android Problem Overview


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.

Android Solutions


Solution 1 - Android

Anyway, the documentation covers all the things.

Changing menu items at runtime

> Once the activity is created, the > onCreateOptionsMenu() method is called > only once, as described above. The > system keeps and re-uses the Menu you > define in this method until your > activity is destroyed. If you want to > change the Options Menu any time after > it's first created, you must override > the onPrepareOptionsMenu() method. > This passes you the Menu object as it > currently exists. This is useful if > you'd like to remove, add, disable, or > enable menu items depending on the > current state of your application.

E.g.

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
	if (isFinalized) {
		menu.getItem(1).setEnabled(false);
        // You can also use something like:
        // menu.findItem(R.id.example_foobar).setEnabled(false);
    }
	return true;
}

On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().

Solution 2 - Android

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

Solution 3 - Android

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

Solution 4 - Android

simplify @Vikas version

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
   
    menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
    return true;
}

Solution 5 - Android

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

Solution 6 - Android

the best solution when you are perform on navigation drawer

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

Solution 7 - Android

If visible menu

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

If hide menu

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

Solution 8 - Android

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>

Solution 9 - Android

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

Solution 10 - Android

  @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

                case R.id.item_id:
                
                       //Your Code....

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

Solution 11 - Android

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

Solution 12 - Android

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVikasView Question on Stackoverflow
Solution 1 - AndroidVikasView Answer on Stackoverflow
Solution 2 - AndroidFrankView Answer on Stackoverflow
Solution 3 - AndroidnirView Answer on Stackoverflow
Solution 4 - AndroidKosrat D. AhmadView Answer on Stackoverflow
Solution 5 - AndroidGastón SaillénView Answer on Stackoverflow
Solution 6 - AndroidPrashant GosaiView Answer on Stackoverflow
Solution 7 - Androidmurugan maniView Answer on Stackoverflow
Solution 8 - AndroidExpensiveBellyView Answer on Stackoverflow
Solution 9 - AndroidSmitty-Werben-Jager-ManjensonView Answer on Stackoverflow
Solution 10 - AndroidTousif AkramView Answer on Stackoverflow
Solution 11 - Androiduser3913975View Answer on Stackoverflow
Solution 12 - AndroidEricView Answer on Stackoverflow