showasaction item invalidateoptionsmenu bar android android-actionbar xamarin android-menu android-optionsmenu

item - Android-Uso correcto de invalidateOptionsMenu()



menu item android (7)

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 pueda ser útil.

Quiero decir, por ejemplo, digamos que queremos agregar un nuevo elemento de ActionBar a nuestra ActionBar , simplemente podemos obtener el menú de onCreateOptionsMenu(Menu menu) y utilizarlo en la acción de cualquier botón.

Ahora, para mi pregunta real, ¿es la única forma 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 nuevamente en el botón y aparecerá el menú anterior.

PD Perdón por la sintaxis de C #.


/** * 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); }


Edit: Aquí hay una mejor respuesta a la pregunta.

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

Aquí hay una pregunta relacionada con esta respuesta: Question .


La mejor manera que funcionó para mí se muestra a continuación.

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

  2. Use el 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 (...) coloque los cambios dinámicos del menú después de borrar

Espero que esto ayude...


Un uso que he encontrado es forzar un orden de operaciones entre onResume y onCreateOptionsMenu/onPrepareOptionsMenu . El orden natural (a partir de la plataforma 22 por lo menos) parece girar alrededor, especialmente cuando se reorienta su dispositivo.

Llame a invalidateOptionsMenu () en onResume () y garantizará que se llamará a onPrepareOptionsMenu después de onResume (también se puede llamar antes). Por ejemplo, esto permitirá habilitar un elemento de menú basado en los datos recuperados en onResume .


Use esto para volver a cargar el nuevo menú durante el ciclo de vida de la aplicación:

ActivityCompat.invalidateOptionsMenu(getActivity());


invalidateOptionsMenu() se usa para decir Android, el contenido del menú ha cambiado y el menú se debe volver a dibujar. Por ejemplo, hace clic en un botón que agrega otro elemento de menú en tiempo de ejecución, u 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 el sistema operativo onPrepareOptionsMenu() , donde implementa las manipulaciones de menú necesarias. Además, OnCreateOptionsMenu() se llama solo una vez durante la creación de la actividad (fragmento), por lo que los cambios en el menú en tiempo de ejecución no pueden ser manejados por este método.

Todo se puede encontrar en la documentation :

Después de que el sistema llame a onCreateOptionsMenu (), retiene una instancia del menú que llena y no llamará a onCreateOptionsMenu () nuevamente a menos que el menú se invalide por alguna razón. Sin embargo, debe usar onCreateOptionsMenu () solo 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 según los eventos que ocurren durante el ciclo de vida de la actividad, puede hacerlo en el método onPrepareOptionsMenu (). Este método le pasa el objeto Menú tal como existe actualmente para que pueda modificarlo, como agregar, eliminar o deshabilitar elementos. (Los fragmentos también proporcionan una devolución de llamada onPrepareOptionsMenu ()).

En Android 2.3.x y versiones inferiores, el sistema invoca enPrepareOptionsMenu () cada vez que el usuario abre el menú de opciones (presiona el botón Menú).

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


onPrepareOptionsMenu() anular el método onPrepareOptionsMenu() , escriba su código de actualización del menú de acción en el mismo método y si está utilizando el fragmento, agregue setHasOptionsMenu(true); en onCreateView() .

Espero te ayude