Android – Uso correcto de invalidateOptionsMenu ()

He estado buscando mucho en invalidateOptionsMenu() y sé lo que hace. Pero no puedo pensar en ningún ejemplo de la vida real donde este método podría ser útil.

Quiero decir, por ejemplo, digamos que queremos añadir un nuevo MenuItem a nuestra ActionBar , simplemente podemos obtener el Menú de onCreateOptionsMenu(Menu menu) y usarlo en la acción de cualquier botón.

¿Ahora a mi pregunta verdadera, está siguiendo la única manera de usar invalidateOptionsMenu() ?

 bool _OtherMenu; protected override void OnCreate (Bundle bundle) { _OtherMenu = false; base.OnCreate (bundle); SetContentView (Resource.Layout.Main); Button button = FindViewById<Button> (Resource.Id.myButton); button.Click += delegate { if(_OtherMenu) _OtherMenu = false; else _OtherMenu = true; InvalidateOptionsMenu (); }; } public override bool OnCreateOptionsMenu (IMenu menu) { var inflater = this.SupportMenuInflater; if(_OtherMenu) inflater.Inflate (Resource.Menu.another_menu, menu); else inflater.Inflate (Resource.Menu.main_activity_menu, menu); return base.OnCreateOptionsMenu (menu); } 

Haga clic en el botón y aparecerá un menú diferente. Haga clic de nuevo en el botón y aparecerá el menú anterior.

PS Lo siento por la sintaxis de C #.

invalidateOptionsMenu() se utiliza para decir Android, que el contenido del menú ha cambiado, y el menú debe volver a dibujarse. Por ejemplo, hace clic en un botón que agrega otro elemento de menú en tiempo de ejecución o se oculta el grupo de elementos de menú. En este caso debe llamar a invalidateOptionsMenu() , para que el sistema pueda volver a dibujarlo en la interfaz de usuario. Este método es una señal para que OS llame a onPrepareOptionsMenu() , donde implementa las manipulaciones de menú necesarias. Además, OnCreateOptionsMenu() se llama sólo una vez durante la creación de la actividad (fragmento), por lo tanto, los cambios de menú en tiempo de ejecución no pueden ser manejados por este método.

Todo se puede encontrar en la documentación :

Después de que el sistema llama aCreateOptionsMenu (), retiene una instancia del Menú que rellena y no llamará onCreateOptionsMenu () de nuevo a menos que el menú se invalide por alguna razón. Sin embargo, debe utilizar onCreateOptionsMenu () sólo para crear el estado del menú inicial y no para realizar cambios durante el ciclo de vida de la actividad.

Si desea modificar el menú de opciones basado en eventos que se producen durante el ciclo de vida de la actividad, puede hacerlo en el método onPrepareOptionsMenu (). Este método le transmite el objeto Menú como existe actualmente para que pueda modificarlo, como agregar, quitar o deshabilitar elementos. (Los fragmentos también proporcionan una devolución de llamada onPrepareOptionsMenu ()).

En Android 2.3.x e inferior, el sistema llama a OnPrepareOptionsMenu () cada vez que el usuario abre el menú de opciones (presiona el botón Menú).

En Android 3.0 o superior, se considera que el menú de opciones siempre está abierto cuando se presentan elementos de menú en la barra de acción. Cuando se produce un evento y desea realizar una actualización de menú, debe invocar invalidateOptionsMenu () para solicitar que el sistema llame a onPrepareOptionsMenu ().

Utilice esta opción para volver a cargar el nuevo menú durante el ciclo de vida de la aplicación:

 ActivityCompat.invalidateOptionsMenu(getActivity()); 

Necesita reemplazar el método onPrepareOptionsMenu() , escribir el código de actuación del menú de acción en el mismo método y si está utilizando el fragmento, a continuación, agregue setHasOptionsMenu(true); En onCreateView() .

Espero que te ayude

Edit: Aquí está una mejor respuesta a la pregunta.

Un buen uso para invalidateOptionsMenu() es cuando tenemos un ListView y Delete All MenuItem así que cuando el ListView está vacío debemos usar invalidateOptionsMenu() para eliminar el Delete All MenuItem .

He aquí una pregunta relacionada con esta respuesta: Pregunta .

 /** * Set a hint for whether this fragment's menu should be visible. This * is useful if you know that a fragment has been placed in your view * hierarchy so that the user can not currently seen it, so any menu items * it has should also not be shown. * * @param menuVisible The default is true, meaning the fragment's menu will * be shown as usual. If false, the user will not see the menu. */ public void setMenuVisibility(boolean menuVisible) { if (mMenuVisible != menuVisible) { mMenuVisible = menuVisible; if (mHasMenu && isAdded() && !isHidden()) { mHost.onSupportInvalidateOptionsMenu(); } } } 

Ejemplo de menú 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_edit" android:icon="@drawable/ic_edit" android:title="Edit Task" app:showAsAction="always" /> <item android:id="@+id/action_delete" android:icon="@drawable/ic_delete" android:title="Delete Task" app:showAsAction="always" /> <item android:id="@+id/action_check" android:icon="@drawable/ic_check" android:title="Check Task" app:showAsAction="always" /> <item android:id="@+id/action_uncheck" android:icon="@drawable/ic_undo" android:title="Uncheck Task" app:showAsAction="always" /> </menu> 

Código dentro de un fragmento de muestra:

 private boolean isMenuItemChecked; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); setMenuVisibility(false); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.my_menu, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); try { menu.findItem(R.id.action_check).setVisible(!isMenuItemChecked); menu.findItem(R.id.action_uncheck).setVisible(isMenuItemChecked); } catch(Exception e) { Log.e(TAG, "onPrepareOptionsMenu error"); } } public void loadUi(boolean isMenuItemChecked) { this.isMenuItemChecked = isMenuItemChecked; setMenuVisibility(true); } 

La mejor manera que trabajó para mí se demuestra a continuación

  1. Poner el estado inicial del menú en onCreateOptionsMenu (…)

  2. Utilice invalidateOptionsMenu () para forzar onCreateOptionsMenu (…) y onPrepareOptionsMenu (…)

  3. En onPrepareOptionsMenu (…), llame a menu.clear () para eliminar todos los elementos del menú.

  4. Todavía en onPrepareOptionsMenu (…) coloca sus cambios dinámicos en el menú después de

Espero que esto ayude…

  • No puedo almacenar en caché las imágenes mientras que bindind la imagen usando MvvmCross
  • Error: no se encontró ningún recurso que coincida con el nombre dado (en 'MvxItemTemplate' con el valor '@ layout / itemc')
  • No se puede establecer la propiedad en un fragmento con varias instancias
  • MapWithOverlaysActivity - No se pudo determinar $ (TargetFrameworkVersion)
  • Xamarin.Droid causando errores de compilación en Visual Studio 2015 cuando se utiliza Xamarin.Forms
  • Iccp: No reconoce el perfil sRGB conocido que se ha editado
  • Nativo de Google Plus Login para Xamarin.Android y Xamarin.iOS
  • Xamarin Forms Android App Crashes ejecutando Debug con VS Android emulador
  • ¿Se ejecutará una aplicación con armeabi sólo en dispositivos armeabi-v7a?
  • Mono para Android - Arquitectura soportada - Drop x86?
  • Bloquee la orientación de la pantalla a la vertical al escanear con la librería Zxing, la aplicación Xamarin.android.
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.