android android-actionbar actionbarsherlock android-holo-everywhere

android - Forzar el menú de desbordamiento en ActionBarSherlock



android-actionbar android-holo-everywhere (4)

Quiero que el menú de desbordamiento de 4.0+ se use en dispositivos pre ICS (2.3 - 2.1). Estoy usando HoloEverywhere con ActionBarSherlock.

Intenté la siguiente solución:

ActionBarSherlock & HoloEverywhere - Forcing Overflow?

pero no funciona porque absForceOverflow no existe. ¿Se eliminó en la versión más nueva o algo así? Revisé los archivos R de los proyectos de la biblioteca ABS y HE y el campo simplemente no está allí.

El tema de mi aplicación está configurado en @style/Holo.Theme.Sherlock.Light y ese es el tema del que estaba tratando de heredar y agrega el parámetro absForceOverflow establecido en true .


A partir de ActionbarSherlock 4.2, hemos perdido la capacidad de gestionar la visibilidad del menú de desbordamiento. Para hacerlo funcionar, necesita combinar 2 enfoques:

  1. Para forzar la visibilidad del menú para Android 3.x (nido de abeja) y superior, necesita utilizar this versión de Android de comprobación de hack + add:

    public static final int DEVICE_VERSION = Build.VERSION.SDK_INT; public static final int DEVICE_HONEYCOMB = Build.VERSION_CODES.HONEYCOMB; if (DEVICE_VERSION >= DEVICE_HONEYCOMB) // Code from answer above

  2. Menú abierto para dispositivos pre-honeycomb:

    • Abra ActionBarSherlock/src/com/actionbarsherlock/internal/view/menu/ActionMenuPresenter.java , vaya al método reserveOverflow
    • Reemplace el original con:

      public static boolean reserveOverflow (contexto contextual) {return true; }

    Esto obligará al menú a mostrar ...

    • pero al hacer clic en el menú emergente del menú no aparece. Para lograr esto, necesitamos anular esto en su clase de actividad :

      @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (DEVICE_VERSION < DEVICE_HONEYCOMB) { if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MENU) { openOptionsMenu(); return true; } } return super.onKeyUp(keyCode, event); }

Después de estas acciones, debe tener el menú de la barra de acciones de desbordamiento totalmente funcional para todas las versiones de Android.


Como ha señalado Siddharth Lele , se ha eliminado en la última versión de ABS para comportarse de la misma manera que la barra de acción real. Por lo tanto, a primera vista, renunciar a mostrar este menú es la mejor opción.

Sin embargo, el menú de desbordamiento que se muestra en la pantalla para algunos dispositivos y no se muestra para otros es, en mi opinión, un gran defecto de diseño en la barra de acción de Android. Este es el por qué:

En dispositivos con una tecla de menú de hardware, el menú no se mostrará en la barra de acciones. La tendencia en los dispositivos más recientes es reducir al mínimo el número de botones HW, ya que se considera más fácil de usar (y porque los iPhones no tienen más que un botón, entonces copian este diseño). Otros fabricantes incluyen el botón de menú, pero está oculto a menos que presione sobre él (sí, se enciende cuando ya no necesita la luz. No es un diseño inteligente, pero de nuevo, cuando todos los botones están apagados, el teléfono parece más fruncido).

Para comprender mejor las implicaciones de esto, veamos un ejemplo: el usuario A tiene un dispositivo con la tecla de menú. Está usando su cliente de correo favorito. Las opciones para configurar cuentas de correo se colocan en el menú de desbordamiento, junto con las opciones habituales (ayuda, acerca de, etc.). Le gustaría agregar una segunda cuenta, pero no tiene idea de cómo llegar a este menú. No hay información en la pantalla para ayudarlo a darse cuenta de lo que debe hacer. Entonces el usuario A le pregunta a su amigo B , quien también está usando este cliente de correo. El usuario B tiene el último Googlephone Nexus N + 1 y puede ver el icono de desbordamiento en la barra de acciones porque su dispositivo no tiene una tecla de menú HW. Muestra A cómo puede agregar una 2da cuenta abriendo este menú. El usuario A ahora está totalmente confundido, ya que están usando las mismas versiones de la aplicación. Frustated, A podría pensar que el problema está en su teléfono por ser demasiado viejo. B también está confundido también.

En este punto, podría pensar que tanto A como B son tontos que no saben cómo usar un teléfono inteligente. Pero a diferencia de las aplicaciones de escritorio, la gran mayoría de los usuarios de teléfonos inteligentes no conocen los conceptos básicos sobre sus dispositivos. Su teléfono anterior bien podría haber sido un dispositivo de teclado con un firmware simple. La batería se apagó y fueron a la tienda para reemplazarla, pero se quedó sin existencias. Podrían haber pedido uno en internet, pero era más caro que comprar un teléfono más nuevo. Entonces se les vendió un teléfono con pantalla táctil porque así es como están los teléfonos hoy en día. Ahora tienen que enfrentarse a una computadora pequeña con un SO completo. Para empeorar las cosas, el teléfono viene solo con una "guía de inicio rápido", y para obtener el manual completo, tienen que descargar un pdf de Internet. ¿Adivina qué? Ellos no lo harán.

Si está desarrollando una aplicación móvil, debe suponer que el usuario podría no saber nada sobre computadoras, el sistema operativo o aplicaciones similares. Debe hacer que la GUI se vea similar en todos los dispositivos, para que las personas puedan aprender y recordar cómo usarla. No culpe a los diseñadores de Action Bar: si los usuarios como A o B no saben cómo ir al menú de opciones , es su culpa en primer lugar. Es por eso que debería haber incluido un medio para llegar a la pantalla de opciones siempre visible.

Algo similar sucede con la tecla Atrás. Algunos dispositivos pueden tener una tecla de retroceso HW, los más nuevos por lo general no. Pero cada vez que podemos volver a nuestras aplicaciones, siempre mostramos ese botón en forma de flecha en la barra de acciones, ¿verdad? Y sí, sé que un botón navega hacia atrás en el "árbol de navegación" mientras que el otro "retrocede en el tiempo", pero esta también es otra falla de diseño: para el usuario malo, la parte de atrás acaba de regresar. Él tiene este botón en la pantalla y también puede usar el HW, pero esto es opcional. Lo mismo debería haberse hecho con el menú de desbordamiento.

Entonces, si piensas (como yo) que este es un botón importante, no te rindas. Proporcione un menú de opciones principales regular y rellene con los submenús pertinentes. Conviértalo en un botón de acción y asígnele un icono descriptivo, o incluso una descripción textual como "MENÚ". También puedes imitar el ícono del menú de desbordamiento, solo usa uno de estos elementos arrastrables:

// For ActionBarSherlock abs__ic_menu_moreoverflow_normal_holo_dark.png abs__ic_menu_moreoverflow_normal_holo_light.png // For ActionBar ic_menu_moreoverflow_normal_holo_light.png ic_menu_moreoverflow_normal_holo_dark.png

Además: ve y copia y pega las imágenes en la carpeta de res de tu proyecto. Nunca se puede saber si las versiones futuras de ABS o la próxima implementación de ActionBar las incluirán.


Encuentro que la respuesta de Exterminator13 no funciona en algunos tipos de dispositivos Android (el número total creo que es bastante pequeño), pero para ajustar tantos dispositivos como sea posible, uso el diálogo y uso un menú con android: showAsAction = "always" como botón de menú de desbordamiento.Después de todo, el efecto del menú de desbordamiento de la barra de acciones de bloqueo se realiza por su origen, así que ¿por qué no realizar el efecto por nuestra cuenta si no es tan problemático? Si entiendes chino, también puedes ver mi blog .

<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/more" android:icon="@drawable/overflow" android:showAsAction="always" /> </menu>

private Dialog popupDialog; private Boolean popupState=false; public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: this.finish(); return true; case R.id.more: if (!popupState) { showPop(); }else { popupDialog.dismiss(); } default: return super.onOptionsItemSelected(item); } } private void showPop(){ LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(ResID, null); ListView listView = (ListView) view.findViewById(ResID); listView.setAdapter(yourOwnAdapter); popupDialog = new Dialog(WifiAuthWireActivity.this); popupDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); popupDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE)); popupDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); popupDialog.setContentView(view); // Calculate ActionBar height TypedValue tv = new TypedValue(); ActionBar maActionBar=getSupportActionBar(); int actionBarHeight=maActionBar.getHeight(); if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); } WindowManager.LayoutParams wmlp = popupDialog.getWindow().getAttributes(); wmlp.gravity = Gravity.TOP | Gravity.RIGHT; wmlp.x+=12; wmlp.y+=actionBarHeight; popupDialog.getWindow().setAttributes(wmlp); popupDialog.show(); }


Si está utilizando la Versión 4.2.0, entonces los temas .ForceOverflow han sido eliminados.

Fuente: Registro de cambios de la versión 4.2.0

Extracto del registro de cambios:

Add SearchView widget for standard search interaction (API 8+ only) Fix: ShareActionProvider in the split action bar no longer fills the entire screen. Fix: ShareActionProvider now does file I/O on a background thread. Fix: Automatically correct ColorDrawable not respecting bounds when used as a stacked background. Fix: Ensure fragments collection is present before dispatching events. Fix: XML-defined onClick searches the correct context for the declared method. Fix: Ensure action mode start/finish callbacks are invoked on the activity for the native action bar. Fix: Allow tab callbacks to have a fragment transaction instance for any FragmentActivity. Fix: Ensure CollapsibleActionView callbacks are dispatched in both native and compatbility action bars. Fix: Remove .ForceOverflow themes. These never should have been included.

Si necesita forzar el desbordamiento, necesitará descargar una versión anterior de ABS. Puede obtener una lista de descargas según su historial de versiones aquí: http://actionbarsherlock.com/download.html

Personalmente todavía uso la versión ABS 4.1.0 ya que actualmente no quiero hacer cambios secundarios en mi aplicación. También uso esto en mi theme.xml :

<style name="MyTheme" parent="@style/Theme.Sherlock.ForceOverflow"> <item name="android:windowBackground">@color/background</item> <item name="actionBarStyle">@style/Widget.Styled.ActionBar</item> <item name="android:actionBarStyle">@style/Widget.Styled.ActionBar</item> </style> <style name="MyTheme.ForceOverflow"> <item name="absForceOverflow">true</item> </style>

Y al aplicar un tema para una Activity en el "@style/Theme.SociallyYOU" manifest.xml , utilizo esto como el atributo: "@style/Theme.SociallyYOU"

De nuevo, si debe forzar el desbordamiento, también puede leer el pensamiento de CommonsWare sobre el mismo en otra pregunta aquí: https://.com/a/12872537/450534 .

NOTA: Una vez dicho esto, siempre es mejor usar la última versión si las compensaciones no son críticas. Al publicar cómo fuerzo el menú de desbordamiento, no estoy sugiriendo que use una versión anterior ni lo recomiendo. Simplemente te está informando de las posibilidades.