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:

 <?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: Con todos los artículos en

Retrato: Estrecha ActionBar con desbordamiento (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: Estrecha ActionBar con todos los elementos en (Esto está bien, pero inconsistente)

Paisaje, cuando empecé en retrato: ActionBar de gran tamaño con desbordamiento 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.

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. } } 
  • ¿Cómo puedo cambiar el menú de la opción en diversos fragmentos?
  • El elemento ITEM no está permitido en MENU
  • Cambiar programaticamente el icono de ActionBar
  • Cómo quitar espacio extra en blanco de Menú
  • El menú de desbordamiento no se muestra en Android 4.2.2
  • ¿Cómo crear un TextView en el menú res \?
  • Desapareciendo el título de la barra de herramientas
  • Cómo crear un subnivel en el menú de navegación en android?
  • PopupWindow - Descartar cuando se hace clic fuera
  • Menú de opciones personalizadas para cada fragmento
  • Cómo parametrizar las opciones de un menú en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.