¿Cómo puedo actualizar el ActionBar cuando onPrepareOptionsMenu ha cambiado las entradas de menú?

Dentro de mis aplicaciones a menudo activar / desactivar entradas de menú y hacerlos visibles desde onPrepareOptionsMenu.

Hoy empecé a añadir el atributo de menú android: showAsAction a algunas de mis aplicaciones de Android 2.x para mostrar las entradas de menú más utilizadas en ActionBar.

El ActionBar no refleja inmediatamente la habilitación / deshabilitación y visibilidad. Necesito hacer clic en el menú desplegable de la derecha para ver este cambio.

Ok, entiendo que el menú se enciende onPrepareOptionsMenu. ¿Pero qué debo hacer para actualizar el ActionBar? Creo que este cambio debe aplicarse desde dentro onOptionsItemSelected, pero no sé lo que debo llamar.

Aquí está el menú:

<item android:icon="@drawable/ic_menu_mapmode" android:id="@+id/men_mapview" android:showAsAction="ifRoom|withText" android:title="@string/txt_mapview" /> <item android:icon="@drawable/ic_menu_mapmode" android:id="@+id/men_satelliteview" android:showAsAction="ifRoom|withText" android:title="@string/txt_satelliteview" /> 

Aquí está el onPrepareOptionsMenu:

 @Override public boolean onPrepareOptionsMenu(final Menu menu) { MenuItem menuItemMapView = menu.findItem(R.id.men_mapview); MenuItem menuItemSatelliteView = menu.findItem(R.id.men_satelliteview); if (mapView.isSatellite()) { menuItemMapView.setEnabled(true).setVisible(true); menuItemmenuItemSatelliteView.setEnabled(false).setVisible(false); } else { menuItemMapView.setEnabled(false).setVisible(false); menuItemmenuItemSatelliteView.setEnabled(true).setVisible(true); } return super.onPrepareOptionsMenu(menu); } 

Aquí está onOptionsItemSelected

 @Override public boolean onOptionsItemSelected(final MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.men_mapview: mapView.setSatellite(false); mapView.setStreetView(true); mapView.invalidate(); invalidateOptionsMenu(); // This works on Android 3.x devices only return true; case R.id.men_satelliteview: mapView.setSatellite(true); mapView.setStreetView(false); mapView.invalidate(); invalidateOptionsMenu(); // This works on Android 3.x devices only return true; } return super.onOptionsItemSelected(menuItem); } 

EDIT: Si agrego invalidateOptionsMenu esto funciona en aplicaciones Android 3.x pero se bloquea en dispositivos Android 2.x debido a un método que falta. ¿Cuál es la forma recomendada de hacerlo bien?

Mi método de elección es crear una clase de ayuda. Por ejemplo:

 class VersionHelper { static void refreshActionBarMenu(Activity activity) { activity.invalidateOptionsMenu(); } } 

Ahora en su código anterior, reemplace invalidateOptionsMenu(); con:

 if (Build.VERSION.SDK_INT >= 11) { VersionHelper.refreshActionBarMenu(this); } 

Crédito para este método va a CommonsWare (búsqueda de HoneycombHelper, y echa un vistazo a sus libros – muy recomendable)

Gracias a la respuesta aceptada. Estoy utilizando ActionBarActivity. En esta clase puedes usar

 supportInvalidateOptionsMenu(); 

Utilizar

 ActivityCompat.invalidateOptionsMenu(Activity activity) 

Desde la biblioteca de compatibilidad .

Consulte: https://stackoverflow.com/a/14748687/435855

Guardar una referencia al menú y llamar a:

 this.menu.clear(); this.onCreateOptionsMenu(this.menu); 

Ahora puede utilizar el método supportInvalidateOptionsMenu () desde ActionbarActivity con la biblioteca de soporte. Así que no tienes que comprobar la versión de la sdk. Va hasta API 7 y superior.

http://developer.android.com/reference/android/support/v7/app/ActionBarActivity.html

Hacer para ello, tiene que importar la v7 de la biblioteca de soporte utilizando este

http://developer.android.com/tools/support-library/setup.html

Basado en "Klaasvaak" respuesta anterior. Estoy usando su subMenus. Esto funciona para mí:

 // Declare and save the menu as global, so it can be called anywhere. Menu absTopSubMenus; public boolean onCreateOptionsMenu(Menu menu) { absTopSubMenus = menu; // Used for re-drawing this menu anywhere in the codes. // The remainder of your code below } 

Luego, para volver a dibujar esto, simplemente llame a:

 // Redraw the top sub-menu absTopSubMenus.clear(); onCreateOptionsMenu(absTopSubMenus); 

No estoy seguro de que ya lo hayas visto, pero si usas la barra de acciones extensamente y planeas soportar API inferior (> 8), echa un vistazo a la biblioteca de actionBarSherlock. Lo hará para que usted no tiene que la sección de su código de actionBar para los API más bajos y más altos, y luego puede ejecutar:

 runOnUiThread(new Runnable(){ @Override public void run(){ supportInvalidateOptionsMenu(); } }); 

Felicitaciones a @ Klaasvaak por mostrarnos el camino aquí. Utilizo lo siguiente que funciona tanto en pre y post-API de nivel 11:

 private void invalidOptionsMenuHelper() { if (Build.VERSION.SDK_INT >= 11) { invalidateOptionsMenu(); } else if (mOptionsMenu != null) { mOptionsMenu.clear(); onCreateOptionsMenu(mOptionsMenu); } } 

Por supuesto, debes guardar una referencia al menú (mOptionsMenu en este caso) que logro mediante:

 @Override public boolean onCreateOptionsMenu(Menu menu) { mOptionsMenu = menu; //... create and manage the menu normally } 

GetActivity (). InvalidateOptionsMenu ();

Hace el trabajo.

También asegúrese de no llamar

 myAppCompatActivity.setToolbarTitle("some dynamic title"); 

Poco después de haber actualizado su menú.

Tuve la edición que los drawables no aparecerían incluso si había sitio para que se exhibieran. Una vez que hice un cambio de orientación los drawables apareció entonces ..?

En resumen:

Actividad principal:

 public class MainActivity extends AppCompatActivity { private boolean showMenu = true; public void setShowMenu(boolean show) { showMenu = show; supportInvalidateOptionsMenu(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_menu, menu); menu.findItem(R.id.menu_share).setVisible(showMenu); // menu.findItem(... return true; } } 

FragmentNoMenu:

 public abstract class FragmentNoMenu extends Fragment { protected MainActivity mainActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mainActivity = (MainActivity) getActivity(); if (mainActivity != null) { mainActivity.setShowMenu(false); } } } 

FragmentWithMenu:

 public abstract class FragmentWithMenu extends Fragment { protected MainActivity mainActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mainActivity = (MainActivity) getActivity(); if (mainActivity != null) { mainActivity.setShowMenu(true); } } } 
  • Problema XML en el ejemplo del menú básico
  • Android: Detectar mediante programación si el dispositivo tiene botón de menú de hardware
  • El menú de opciones no se mostrará en Android 4.1.1
  • Reducir los elementos del menú anchura, altura y tamaño de texto
  • Menú de la cinta de opciones Android
  • Diálogo de alerta desde dentro de onOptionsItemSelected android
  • Android: Crear un menú de acción rápida
  • Menú deslizante vertical animado en android
  • Google Maps elimina el menú contextual de la ruta del marcador
  • Método de llamada cuando el botón de inicio presionado en android
  • Android añadiendo un submenú a un menuItem, donde es addSubMenu ()?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.