Respuestas:
De todos modos, la documentación cubre todas las cosas.
Una vez que se crea la actividad, el
onCreateOptionsMenu()
método se llama solo una vez, como se describió anteriormente. El sistema mantiene y reutiliza loMenu
que defina en este método hasta que se destruya su actividad. Si desea cambiar el menú de opciones en cualquier momento después de que se creó por primera vez, debe anular elonPrepareOptionsMenu()
método. Esto le pasa el objeto Menú tal como existe actualmente. Esto es útil si desea eliminar, agregar, deshabilitar o habilitar elementos de menú según el estado actual de su aplicación.
P.ej
@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;
}
En Android 3.0 y versiones posteriores, se considera que el menú de opciones siempre está abierto cuando los elementos del menú se presentan en la barra de acción. Cuando se produce un evento y desea realizar una actualización del menú, debe llamar invalidateOptionsMenu()
para solicitar que el sistema llame onPrepareOptionsMenu()
.
false
para deshabilitar completamente el menú.
En todas las versiones de Android, la forma más fácil: use esto para MOSTRAR un ícono de acción del menú como deshabilitado Y hacer que FUNCIÓN también esté deshabilitado:
@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);
}
}
Puede guardar el elemento como una variable al crear el menú de opciones y luego cambiar sus propiedades a voluntad.
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);
}
onPrepareOptionsMenu
?
simplifique la versión de @Vikas
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
Cómo actualizar el menú actual para habilitar o deshabilitar los elementos cuando se realiza una AsyncTask.
En mi caso de uso, necesitaba deshabilitar mi menú mientras mi AsyncTask estaba cargando datos, luego, después de cargar todos los datos, necesitaba habilitar todo el menú nuevamente para permitir que el usuario lo usara.
Esto evitó que la aplicación permitiera a los usuarios hacer clic en los elementos del menú mientras se cargaban los datos.
Primero, declaro una variable de estado; si la variable es 0, se muestra el menú; si esa variable es 1, el menú está oculto.
private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.
Luego en mi onCreateOptionsMenu()
compruebo esta variable, si es 1, deshabilito todos mis elementos, si no, solo los muestro a todos
@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);
}
Ahora, cuando comienza mi actividad, onCreateOptionsMenu()
se llamará solo una vez, y todos mis elementos desaparecerán porque configuré el estado para ellos al comienzo.
Luego creo una AsyncTask donde establezco esa variable de estado en 0 en mi onPostExecute()
¡Este paso es muy importante!
Cuando usted llama invalidateOptionsMenu();
se relanzaráonCreateOptionsMenu();
Entonces, después de configurar mi estado a 0, simplemente redibujé todo el menú, pero esta vez con mi variable en 0, dicho esto, todo el menú se mostrará después de que todo el proceso asíncrono se haya realizado, y luego mi usuario puede usar el menú .
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
}
}
la mejor solución cuando se realiza en el cajón de navegación
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
Una respuesta más moderna para una vieja pregunta:
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 onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
Lo que hice fue guardar una referencia al Menú en onCreateOptionsMenu
. Esto es similar a la respuesta de nir, excepto que en lugar de guardar cada elemento individual, guardé todo el menú.
Declarar un menú Menu toolbarMenu;
.
Luego en onCreateOptionsMenu
guardar el menú a su variable
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
toolbarMenu = menu;
return true;
}
Ahora puede acceder a su menú y a todos sus elementos en cualquier momento que desee.
toolbarMenu.getItem(0).setEnabled(false);
@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;
}
Si menú visible
menu.findItem(R.id.id_name).setVisible(true);
Si ocultar menú
menu.findItem(R.id.id_name).setVisible(false);
En general, puede cambiar las propiedades de sus vistas en tiempo de ejecución:
(Button) item = (Button) findViewById(R.id.idBut);
y entonces...
item.setVisibility(false)
pero
si desea modificar la visibilidad de las opciones desde ContextMenu, al presionar su botón, puede activar una bandera, y luego en onCreateContextMenu puede hacer algo como esto:
@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();
}
}
espero que esto ayude
onCreateContextMenu
método. Pero quiero acceder al menú contextual desde este método.
onCreateContextMenu
se llamará solo una vez, pero puedo hacer clic en el botón muchas veces para habilitar / deshabilitar el elemento del menú.
setEnable()
cambia lo que sucede cuando presiona este menú, pero no cambia su aspecto (¿qué pasa, desarrolladores de Android?). Por lo tanto, es más claro deshabilitar y cambiar el título, o preferiblemente simplemente hacer loMenuItem
invisible.