¿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); } } } 
  • ¿Cómo puedo crear iconos para elementos de menú en ListView de Android?
  • Aplicación de notas de capturas de Android como menú de círculo
  • Cómo hacer un menú transparente de lujo como el "menú compartido" en la galería de Android?
  • Android - ActionBarSherlock - Establecer textcolor de texto en el menú
  • Cómo cambiar la sangría de los elementos del submenú en un NavigationView?
  • Android invalidateOptionsMenu () para API <11
  • ¿Cuándo y con qué frecuencia se llama al método onPrepareOptionsMenu () para ActionBar?
  • Cómo ocultar el menú de opciones?
  • ¿Cómo agregar un menú en un fragmento?
  • Cómo cambiar el tamaño del texto del menú
  • Barra de acciones - elemento del submenú con texto e imagen no funcionando correctamente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.