La barra de acción de Android no muestra desbordamiento

90

Tengo una barra de acción en mi aplicación con 3 elementos.

Solo se pueden mostrar 2 debido a problemas de espacio, por lo que esperaría que se muestre el primero y el resto se muestre en el desbordamiento. Sin embargo, en la práctica, solo se muestran los 2 primeros elementos y no se detecta un desbordamiento.

Aquí está el código relevante: list_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_insert"
    android:icon="@android:drawable/ic_menu_add"
    android:title="@string/menu_insert" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_call"
    android:icon="@android:drawable/ic_menu_call"
    android:title="@string/menu_call" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_agenda"
    android:icon="@android:drawable/ic_menu_agenda"
    android:title="@string/menu_agenda" 
    android:showAsAction="ifRoom|withText"/>
</menu>

Activity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater mi = getMenuInflater();
    mi.inflate(R.menu.list_menu, menu);
    return true;
}
Alfombrillas Raemen
fuente
120
Si su dispositivo tiene un botón de menú, el icono de desbordamiento no se mostrará. ¿En qué dispositivo estás?
Reinier
1
el dispositivo virtual en el que estoy probando tiene un botón de menú, hice clic en él y apareció el elemento que faltaba, ¡gracias!
Mats Raemen
2
@Reinier Estoy usando ActionBarSherlock. En Galaxy Ace con 2.3 se muestra, en Galaxy SII con 4.0 no se muestra. Ambos tienen botón de menú HW.
Mister Smith
2
Quería confirmar que esto me tenía desconcertado de que tuviera el ícono de desbordamiento en una compra de nexus 7, no en Galaxy Note II. El Note tenía un botón de menú. ¡Gracias!
bsautner
@Reinier, por favor, ayúdame a enfrentar el mismo problema, ¿qué debo hacer?
rupesh

Respuestas:

125

Si desea mostrar los tres puntos, independientemente del botón de menú del dispositivo. entonces puedes llamar a este método en tu clase de aplicación 'método onCreate-

private void makeActionOverflowMenuShown() {
    //devices with hardware menu button (e.g. Samsung Note) don't show action overflow menu
    try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if (menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage());
    }
}
Atul Kaushik
fuente
32
Este es un truco horrible que rompe la coherencia con el resto de las aplicaciones de la plataforma. No hagas esto.
adamp
19
Este parece el menor de dos males. El comportamiento actual es inaceptable.
biorbnA
6
Es una excelente manera de permitir el desbordamiento, la tecla física del menú ya no debe tolerarse.
Necronet
5
¡Funciona genial! Funciona incluso si el usuario presiona el botón del menú del hardware (que es brillante), aunque escuchará el efecto de sonido del menú dos veces ... ¿Alguien sabe cómo hacer que suene solo una vez?
Bruce
5
ESTO NO ES UN HACK. Los desarrolladores necesitan saber cómo llamar hacks, ya que no es 2 + 2 en Android. La reflexión está ahorrando tiempo usando mecanismos de Java, o de lo contrario estaría pasando contextos a sus clases internas 24/7, o personalizando AOSP hasta el infinito. Para mí, esta solución resuelve el problema de tener que anular e incluir toneladas de contenido personalizado AOSP Y asociaciones privadas vinculadas solo por el bien de lo que los puristas consideran limpio. ¿Sabía que no puede forzar FASTSCROLL habilitado de manera consistente para listas pequeñas? Antes de usar la reflexión, esto requería que copiara más de 10 recursos AOSP, para una edición de UN carácter.
leRobot
54

Barra de acciones

res / menu / menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- Search / will display always -->
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="always"
        android:title="@string/action_search"/>

    <!-- Location Found -->
    <item
        android:id="@+id/action_location_found"
        android:icon="@drawable/ic_action_location_found"
        android:showAsAction="always"
        android:title="@string/action_location_found"/>

    <!-- More -->
    <item
        android:id="@+id/a_More"
        android:icon="@drawable/ic_action_overflow"
        android:showAsAction="always"
        android:title="More">
        <menu>

            <!-- Refresh -->
            <item
                android:id="@+id/action_refresh"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_refresh"/>

            <!-- Help -->
            <item
                android:id="@+id/action_help"
                android:icon="@drawable/ic_action_help"
                android:showAsAction="never"
                android:title="@string/action_help"/>

            <!-- Check updates -->
            <item
                android:id="@+id/action_check_updates"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_check_updates"/>
        </menu>
    </item>

</menu>

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

}

Descargar el conjunto de iconos de la barra de acción

Kirit Vaghela
fuente
2
Eche un vistazo al comentario de @Reinier, es cierto "Si su dispositivo tiene un botón de menú, el icono de desbordamiento no se mostrará".
Ahmad Dwaik 'Warlock'
Pruebo en el dispositivo que tiene un botón de menú y se muestra un desbordamiento en mi caso. Lo uso android:showAsAction="always"para más artículos
Kirit Vaghela
¿en qué dispositivo lo has probado? He usado un xperia neo v y s #
Ahmad Dwaik 'Warlock'
1
Nota: Su artículo que infla su menú adicional DEBE mostrarAsAction = "always"
Kirit Vaghela
1
showAsAction no está disponible en el espacio de nombres de Android en SDK más antiguos. Siga este enlace developer.android.com/training/basics/actionbar/… para superar esto. Después de agregar este NS schemas.android.com/apk/res-auto , el truco anterior funcionó perfectamente bien para mí
chedine
42

Me doy cuenta de que este no es un menú adicional, pero es similar. Está bien, esto es simple pero fue difícil de entender.

Primero necesita un elemento de menú que desee utilizar como inflador de desbordamiento. Ejemplo

<item
        android:id="@+id/a_More"
        android:icon="@drawable/more"
        android:showAsAction="always"
        android:title="More">
        </item>

Una vez que tenga su artículo, agregue un submenú que contenga los artículos que desee en el menú adicional. Ejemplo:

<item
    android:id="@+id/a_More"
    android:icon="@drawable/more"
    android:showAsAction="always"
    android:title="More">
    <menu>
        <item
            android:id="@+id/aM_Home"
            android:icon="@drawable/home"
            android:title="Home"/>
    </menu>
</item>

Al hacer clic, esto inflará otros elementos dentro. Mi aplicación utiliza ActionBarSherlock 4.0, por lo que antes de que funcione, deberá acceder a "SplitActionBar". (Seguirá funcionando en la barra de acción predeterminada de Android)

He aquí cómo: En su archivo AndroidManifest.xml, debe agregar este código debajo de la actividad en la que necesita el menú adicional.

android:uiOptions="splitActionBarWhenNarrow"

NOTA: Su artículo que infla su menú adicional DEBEshowAsAction="always"

¡Vwola! tienes un menú desbordado! Espero haberte ayudado. :)

LeviRockerSk8er
fuente
3
Buena solución, mejor que el truco del botón del menú.
ol0
26

En dispositivos con botones de menú de hardware (Galaxy S3, terco como es Samsung ...) el menú adicional se comporta como el menú 'tradicional', usando el botón de menú de hardware.

Lukas Batteau
fuente
2
La respuesta anterior, sin embargo, con la biblioteca de compatibilidad, simplemente tropieza con resultados muy extraños: 3 dispositivos con botón de hardware, Note 3 Neo = Se muestra el menú de desbordamiento, el botón de menú no funciona, Nota 1 = Sin desbordamiento, el botón de menú funciona, Galaxy S3, no desbordamiento, el botón de menú no funciona! Esto es Loco.
3c71
5

Cuando dice menú "desbordado", ¿se refiere a los tres puntos que aparecen al final para indicar que hay más elementos ... o se refiere a la barra de acción dividida que aparece en la parte inferior para los elementos desbordados?

Si te refieres a la barra de acción dividida, debes agregar esto al archivo de manifiesto de tu actividad

android:uiOptions="splitActionBarWhenNarrow"

De forma predeterminada, el menú de desbordamiento de tres puntos debería ocurrir automáticamente, por lo que es difícil saber cuál es el problema a partir de la información que proporcionó anteriormente.

wnafee
fuente
Me refiero a los tres puntos. No es que sea por los artículos, porque cada vez que se cambian los artículos de pedido, son los primeros 2 íconos los que se muestran
Mats Raemen
¿Debo proporcionar información adicional para poder determinar el problema real?
Mats Raemen
¿Cuáles son su minSdkVersion, targetSdkVersion y la versión en la que está probando?
Sparky
5
¿Su dispositivo tiene botones físicos para el menú o son botones virtuales como el teléfono galaxy nexus? Creo que los tres puntos solo aparecerán si su teléfono no tiene botones físicos.
Tarifa del
5

Para mostrar siempre el desbordamiento de la acción (tres puntos) en actionbarcompat:
en el archivo de menú, ejemplo:
main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_about"
        android:title="@string/action_about"
        app:showAsAction="never"/>

</menu>

y en el archivo de actividad:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
}

Me ha funcionado bien.
Probado en Google Nexus S, Samsung S3.

MrSiro
fuente
3

Parece que en los dispositivos con un botón de menú, el menú adicional no se muestra en la barra de acciones. Además, no tenemos forma de saber si un dispositivo tiene un botón de menú de hardware antes del nivel de API 14 (4.0+).

Esta solución agrega un botón de desbordamiento android.support.v7.app.ActionBarque abre el menú de opciones estándar solo en la versión anterior a Honeycomb (<3.0), de lo contrario, lo deja en manos del sistema. En cualquier caso, puede elegir entre alwayso ifRoompara todas las acciones.

Obtenga el icono de desbordamiento del paquete de iconos de la barra de acciones .

Agregue un menú (omito algunas partes no relevantes como títulos, pedidos, etc.)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

<item
    android:id="@+id/action_overflow"
    android:orderInCategory="100"
    android:icon="@drawable/ic_action_overflow"
    app:showAsAction="always" />

<item
    android:id="@+id/action_first"
    app:showAsAction="always" />

<item
    android:id="@+id/action_second"
    app:showAsAction="ifRoom" />

</menu>

Elimina nuestra acción de desbordamiento en 3.0+

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        menu.removeItem(R.id.action_overflow);
    }
    return super.onPrepareOptionsMenu(menu);
}

Finalmente llame Activity.openOptionsMenu()desde la acción de desbordamiento.

Er ... no. No puede no llamar openOptionsMenu()desde un botón de menú ... pero si está usando AndroidAnnotations, lo hace fácilmente:

@OptionsItem
void action_overflow() {
    openOptionsMenuDeferred();
}

@UiThread
void openOptionsMenuDeferred() {
    openOptionsMenu();
}

Si no deberías hacer algo como esto, supongo

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == id.action_overflow) {
        openOptionsMenuDeferred();
        return true;
    }
}

private Handler handler = new Handler(Looper.getMainLooper());
public void openOptionsMenuDeferred() {
    handler.post(new Runnable() {
        @Override
        public void run() {
            openOptionsMenu();
        }
    }
    );
}
IlDan
fuente
2

Intente cambiar el tema de la aplicación de Theme.AppCompat.Light.DarkActionBar a Theme.AppCompat.Light

Sagar Devanga
fuente
2

Coloque la xmlns:your_app_name="http://schemas.android.com/apk/res-auto"etiqueta del menú dentro y en android:showAsAction="always"su lugar useyour_app_name:showAsAction="always"

por ejemplo

<item
    android:id="@+id/action_search"
    android:icon="@drawable/icon_search"
    android:title="@string/search"
    your_app_name:showAsAction="ifRoom"/>

Rashmi Jain
fuente