Capacidad de ActionBar / desbordamiento que no cambia en cambio de orientación
Tengo una aplicación que usa la ActionBar, donde manejo los cambios de orientación yo mismo:
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
… y el menú debe encajar en el ActionBar sin desbordamiento en el paisaje, pero no en el retrato:
- Cómo implementar un contador de insignia en el icono de menú de hamburguesa android
- Barra de acciones setnavigationmode deprecated
- Elemento con la aplicación: showAsAction no se muestra
- Fragmentos, con el mismo menú, en el mismo diseño causa duplicado menuitem
- Barra de herramientas, onCreateOptionsMenu () devuelve falso, 'arriba' la navegación no funciona
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:title="@string/Game" android:id="@+id/game" android:icon="@android:drawable/ic_menu_manage" android:showAsAction="ifRoom|withText"/> <item android:title="@string/Type" android:id="@+id/type" android:icon="@android:drawable/ic_menu_edit" android:showAsAction="ifRoom|withText"/> <item android:title="@string/Other" android:id="@+id/other" android:icon="@android:drawable/ic_menu_gallery" android:showAsAction="ifRoom|withText"/> <item android:title="@string/Solve" android:id="@+id/solve" android:icon="@android:drawable/ic_menu_directions" android:showAsAction="ifRoom|withText"/> <item android:title="@string/Help" android:id="@+id/help" android:icon="@android:drawable/ic_menu_help" android:showAsAction="ifRoom"/> </menu>
En el inicio, esto funciona correctamente:
Paisaje:
Retrato: (Sí, podría obligar a todos los elementos a mostrar siempre y encajarían, como se muestra a continuación, pero que podría romper en una tableta más pequeña)
Cuando el emulador cambia de orientación, la capacidad de ActionBar no parece cambiar:
Retrato, cuando comencé en el paisaje: (Esto está bien, pero inconsistente)
Paisaje, cuando empecé en retrato: Esto se ve muy tonto y es la razón por la que quiero arreglar esto.
He añadido esta llamada a invalidateOptionsMenu () , pero no ayuda:
@Override public void onConfigurationChanged(Configuration newConfig) { maybeMoveSomeViewsAround(newConfig); super.onConfigurationChanged(newConfig); invalidateOptionsMenu(); }
(En realidad lo llamo por reflexión para compatibilidad con versiones anteriores, pero el depurador me dice que realmente se llama y no encuentra una excepción.)
InvalidateOptionsMenu () en realidad termina llamando onCreateOptionsMenu () (que vuelve a inflar el menú) antes de volver, y puedo ver dentro de este último que getResources (). GetConfiguration (). Orientación ya ha cambiado. Así que esto es realmente desconcertante. Si el menú de opciones está siendo recreado, cuando la orientación ha cambiado, debe ser ActionBar mismo caché de la anchura?
¿Hay una manera de volver a crear la barra de acción sin destruir / crear la actividad? (Porque este último es un poco caro en mi caso)
Editar: Aquí hay un proyecto de muestra mínimo que muestra el problema.
Editar 2: Había pensado en comprobar el ancho de pantalla y programaticamente ajustar los indicadores showAsAction entre siempre y nunca de manera adecuada, pero eso requiere saber (o adivinar) el ancho de cada elemento. La API pública de ActionBar no me ayuda en ese punto.
- Error: no se encontró identificador de recurso para el atributo "showAsAction" en el paquete android
- Utilice diferentes iconos con diferentes versiones de SDK de Android
- Crear un MenuItem de Android con subtítulos mediante programación
- Menú en Fragmentos no mostrados
- ¿Cómo abrir el submenú después de hacer clic en el elemento de menú en el cajón de navegación?
- Android NavigationEntrar la posición del icono equivocado en RTL
- Cambie la dirección de ActionBar
- ¿Cómo puedo obtener el elemento de menú en NavigationView?
Me encontré con este problema y se le ocurrió un hack que funciona al 100%.
Me ened up llamando invalidateOptionsMenu () dos veces. Mira el siguiente código:
private boolean hackActionBarReset = false; @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); //a hack to reset the items in the action bar. hackActionBarReset = true; invalidateOptionsMenu(); hackActionBarReset = false; invalidateOptionsMenu(); }
Y en su onCreateOptionsMenu () establezca esto en usted menuitems que desea mostrar:
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT | (hackActionBarReset ? MenuItem.SHOW_AS_ACTION_NEVER : MenuItem.SHOW_AS_ACTION_IF_ROOM));
No es una solución bonita, pero funciona.
He trabajado cuidadosamente alrededor de esto: cuando el ancho del dispositivo es mayor que 850dip, la fuerza de mostrar todos los elementos en la barra de acción, de lo contrario continuar a dejar que la plataforma decida.
Aquí está el compromiso git . Edit: y el seguimiento se comprometen a corregir usando un campo que es demasiado nuevo, oops. Todos los derechos reservados
Definitivamente todavía estoy interesado en mejores respuestas (aparte de esperar una solución a la plataforma).
Encontré que la solución más simple y más eficaz era despejar el menú y luego reconstruirlo.
Por ejemplo:
Menu menu; @Override public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; // Setup code goes here... } @Override public void onOrientationChanged() { if (menu != null) { menu.close(); // Ensure the menu is closed before changing its contents. menu.clear(); onCreateOptionsMenu(menu); // Rebuild the menu. } }
- Adición de un TableLayout dinámico con bordes en una aplicación para Android
- Notificación de Android para reproducir sólo sonido