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.
- No se puede convertir de int a Android.Graphics.Color
- ¿Cómo se compara Xamarin para Android (Mono para Android) con el desarrollo nativo de Android?
- No se puede crear una carpeta / archivo en el sistema de archivos de Android con PCLStorage o Xamarin Forms Labs
- Cómo inflar una vista en expansión con una vista de relación de aspecto fija
- No puede tener acceso a un miembro no estático de tipo externo X a través de tipo anidado X
¿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 #.
- Obtener la actividad actual de Application.Context - MonoAndroid
- ¿Cuál es la contraparte de iOS 'QLPreviewController o UIDocumentInteractionController en Android?
- ¿Cómo puedo interpretar este seguimiento de la pila de Android?
- Xamarin.Forms SetHasNavigationBar causas falsas salto en PushAsync
- Xamarin AndroidManifest.xml es diferente al de Visual Studio
- Xamarin Android Exception causa "Frame no en el módulo"
- Xamarin.forms mezclando ContentPage y la actividad de Android
- MvvmCross Navegar a ViewModel en la notificación de Android haga clic
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
-
Poner el estado inicial del menú en onCreateOptionsMenu (…)
-
Utilice invalidateOptionsMenu () para forzar onCreateOptionsMenu (…) y onPrepareOptionsMenu (…)
-
En onPrepareOptionsMenu (…), llame a menu.clear () para eliminar todos los elementos del menú.
-
Todavía en onPrepareOptionsMenu (…) coloca sus cambios dinámicos en el menú después de
Espero que esto ayude…