2010-11-16 32 views
41

Tengo un menú de opciones en mi Activity con un MenuItem "Inicio". Cuando este MenuItem está seleccionado, me gustaría modificar el Menú para que contenga un MenuItem "Parar". Y finalmente, cuando se selecciona "Parar", me gustaría volver a "Comenzar".¿Cómo puedo modificar un elemento de menú en el menú de opciones en Android?

Aquí hay partes de mi código que no están funcionando. Tengo tanto "Inicio" y "Stop" que se enumeran en mymenu.xml probablemente debería eliminar el "stop" 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; 
    } 
} 
+1

¿Ya ha tratado de quitar Stop cuando se crea el menú? El código se ve bien. No puedo encontrar nada que pueda causar problemas distintos de eso. –

+0

@Octavian: Intenté con 'menu.removeItem (R.id.stop);' después de 'getMenuInflater();' pero no funcionó. O bien obtengo dos elementos del menú, uno "inicio" y uno "falso" (debería ser "detener"), o el menú se bloquea cuando debería mostrarse. – Jonas

+1

¿dónde está tratando de llamar a 'removeItem()'? En 'onPrepareOptionsMenu()'? –

Respuesta

94

Para este tipo de operación normalmente elegir para no alterar los elementos del menú, pero sólo ocultar los que no es necesario:

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

Acabo de ver que olvidé llamar a la superclase como se sugirió anteriormente y especifiqué en [docs] (http: // developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu%28android.view.Menu%29) y la [fuente] (http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/ core/java/android/app/Activity.java & d = 3 & l = 2272) – Flygenring

+0

Y solo para actualizar, la fuente se puede encontrar en http://grepcode.com/file/repository.grepcode.com/java/ext/com. google.android/android/2.3_r1/android/app/Activity.java?av=f#2272 – Flygenring

6

es probable que tenga que llamar super.onPrepareOptionsMenu después de que haya terminado de realizar los cambios. Desde el docs:

clases Derivado siempre deben llamar a través de la clase base aplicación.

+0

+1 para entregar una respuesta correcta aunque no sea la solución. –

3

Tengo la solución. Básicamente está borrando el MenuItem cuando llama al 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 el MenuInflater mientras crea el código Menu, por lo que tampoco necesita ningún archivo XML de menú.

20

Flygenring respuesta es correcta, pero menu.findItem () es lento y lo llama dentro de onPrepareOptionsMenu (Menú menú) produce mala experiencia de usuario. Es mejor conseguir Menultem objeto una vez mientras que la creación de menús, y luego simplemente llamar setVisible cada vez menú occures 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; 
    } 
1

gracias por la información en este post 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; 
} 
+0

¿En qué archivo debe colocarse? –

Cuestiones relacionadas