programacion - ¿Cómo puedo modificar un MenuItem en el menú de opciones en Android?
manual android studio avanzado (6)
Tengo un menú de opciones en mi Activity
con un elemento de menú "Inicio". Cuando este MenuItem
está seleccionado, me gustaría modificar el Menú para que contenga un MenuItem
"Stop". Y finalmente, cuando se selecciona "Parar", me gustaría volver a "Comenzar".
Aquí hay partes de mi código que no está funcionando. Tengo tanto "Inicio" como "Detener" enumerados en mymenu.xml
. Probablemente debería eliminar "detener" cuando se crea el menú:
public class MyActivity extends Activity {
private boolean isStarted = false;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
menu.removeItem(R.id.stop);
inflater.inflate(R.menu.mymenu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.start:
isStarted = true;
return true;
case R.id.stop:
isStarted = false;
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(isStarted) {
menu.removeItem(R.id.start);
menu.add(R.id.stop);
} else {
menu.removeItem(R.id.stop);
menu.add(R.id.start);
}
return true;
}
}
En Android 3.0 y superior, debe llamar a invalidateOptionsMenu () para solicitar que el sistema llame aPrepareOptionsMenu () . Luego puede modificar el menú de opciones en el método. Puede consultar los elementos del menú Cambiar en la sección de tiempo de ejecución de la documentación de Android aquí https://developer.android.com/guide/topics/ui/menus#options-menu para obtener más detalles.
Para este tipo de operación, generalmente elijo no alterar los elementos del menú, sino simplemente ocultar los que no necesita:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.start).setVisible(!isStarted);
menu.findItem(R.id.stop).setVisible(isStarted);
return true;
}
Probablemente necesites llamar a super.onPrepareOptionsMenu una vez que hayas terminado de hacer los cambios. De los docs :
Las clases de derivación siempre deben llamar a la implementación de la clase base.
Tengo la solución. Básicamente está borrando el MenuItem
cuando llama a removeItem()
y también borra la referencia. Usar este código funciona.
private boolean isStarted = false;
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 1:
isStarted = true;
return true;
case 0:
isStarted = false;
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(isStarted) {
menu.removeItem(1);
menu.add(0, 0, 0, "Stop");
} else {
menu.removeItem(0);
menu.add(0, 1, 0, "Start");
}
return super.onPrepareOptionsMenu(menu);
}
Tienes que crear el MenuItem
nuevamente. Esa es también la razón de la etiqueta false
. En realidad, no necesita MenuInflater
mientras crea el Menu
través del código, por lo que tampoco necesita ningún archivo XML de menú.
gracias por la información en esta publicación ya que resolvió mi problema de las etiquetas falsas en mi menú. Tuve que modificarlo ligeramente y tener el código final que funciona bien de la siguiente manera con la esperanza de que le ahorre a alguien más algo de tiempo y frustración. Es una solución ligeramente diferente, pero el principal cambio que realicé fue el .setVisible True o False, aparte de que la solución de i.shadrins era la que mejor se ajustaba a mis necesidades.
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if(loggedIn)
{
logIn.setVisible(false);
logOut.setVisible(true);
}
else
{
logIn.setVisible(true);
logOut.setVisible(false);
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
logIn = menu.findItem(R.id.loggedOut);
logOut = menu.findItem(R.id.loggedIn);
return true;
}
La respuesta de Flygenring es correcta, pero menu.findItem () está descuidado y llamarlo en onPrepareOptionsMenu (menú de menú) produce una mala experiencia de usuario. Es mejor obtener el objeto MenuItem una vez mientras se crea el menú, y luego simplemente llamar a setVisible cada vez que se muestre el menú en la pantalla:
MenuItem mDynamicMenuItem;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
// Get dynamic menu item
mDynamicMenuItem = menu.findItem(R.id.menu_item);
return true;
}
// Prepare the Screen''s standard options menu to be displayed. This is called right
// before the menu is shown, every time it is shown. You can use this method to
// efficiently enable/disable items or otherwise dynamically modify the contents.
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
// Here is just a good place to update item
mDynamicMenuItem.setVisible(isVisible);
return true;
}