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
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 onCreateOptionsMenu
save 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
}
}
Source: Stackoverflow.com