El elemento de menú de Android 4.3 showAsAction = "siempre" ignorado


116

Estoy usando la nueva biblioteca appcompat v7 disponible a partir de Android 4.3 (nivel de API 18).

Independientemente de lo que se especifique en showAsAction para un elemento de menú, no se muestra; siempre crea el icono de menú de desbordamiento y coloca incluso un solo elemento de menú debajo del menú.

Intentando agregar menú a una actividad como esta:

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

Y aquí está mi menú xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

¿Es un error de la nueva biblioteca de soporte v7 o simplemente hay algún problema con el código? He estado usando el código similar con ActionBarSherlock muchas veces antes.


2
Con fines informativos: "... "always"no se recomienda; es mejor usarlo "ifRoom"y dejar que el sistema operativo decida".
ChiefTwoPencils

Respuestas:


313

Probablemente le falte el espacio de nombres requerido:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:[yourapp]="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        [yourapp]:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

Reemplace [yourapp]con el nombre de su aplicación o cualquier espacio de nombres que su corazón desee en todas partes.

Otras cosas que vale la pena comprobar:

  • Vea si su clase de actividad se extiende ActionBarActivity

Compruebe si el problema persiste.


Documentación de referencia de Android: Agregar botones de acción . Aquí está el texto relevante:

Si su aplicación utiliza la biblioteca de compatibilidad para compatibilidad en versiones tan bajas como Android 2.1, el atributo showAsAction no está disponible en el espacio de nombres android:. En su lugar, este atributo lo proporciona la biblioteca de soporte y debe definir su propio espacio de nombres XML y usar ese espacio de nombres como prefijo de atributo. (Un espacio de nombres XML personalizado debe basarse en el nombre de su aplicación, pero puede ser cualquier nombre que desee y solo es accesible dentro del alcance del archivo en el que lo declara).


2
Eso es lo que también descubrí. Gracias, definitivamente aceptado. Pero showAsAction debería usar ese espacio de nombres personalizado.
Mcingwe

5
'yourapp' significa en String.xml <string name = "app_name"> yourapp </string> ¿verdad?
LOG_TAG

4
¿Alguien puede explicar POR QUÉ esto funciona? ¿Por qué es necesario ampliar un espacio de nombres personalizado? Poco confundido.
Cena el

8
@dineth appcompat se utiliza como un proyecto de biblioteca. Esto significa que todos sus recursos (cadenas, dibujables, atributos ...) se declaran en el espacio de nombres de su aplicación en lugar del espacio de nombres de Android. Como el showAsActionatributo no existía en Android-7, debe usar el espacio de nombres de su aplicación
nicopico

22
Todos dicen "espacio de nombres personalizado" o "un espacio de nombres que coincide con su aplicación". Pero el espacio de nombres siempre está http://schemas.android.com/apk/res-autoen cada ejemplo. No es uno personalizado ni uno que coincida con su aplicación. Ese es el espacio de nombres real de la documentación. Creo que todo el mundo quiere decir un prefijo personalizado , y en realidad puede ser lo que quieras. ¿Es esto cierto?
Andrew Arnott

52

Lo descubrí yo mismo. Con la biblioteca de soporte v7, showAsAction debería ir bajo un espacio de nombres personalizado como este:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:balloonberry="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        balloonberry:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

1
'balloonberry' significa en String.xml "<string name =" app_name "> balloonberry </string>" ¿verdad?
LOG_TAG

5
@LOG_TAG - no, debería ser como se ingresó arriba. Esto no es una cadena, sino un espacio de nombres.
BeccaP

ohhh soporte v7 errr ... está bien en soporte v4
Yasitha Waduge

Gracias por la explicación Mcingwe
Sachidananda Naik

32

También asegúrese de usar el inflador correcto en el método ActionBarActivity.onCreateOptionsMenu ().

Solución correcta:

MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_example, menu);

Solución incorrecta:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);

1
Pasé todas las respuestas anteriores y otras respuestas en stackoverflow, pero lo único que me faltaba es tu respuesta: getMenuInflater (). Gracias por compartir esto.
Amt87

MUCHAS gracias por este. Convertí todos mis más de 100 menús para usar un espacio de nombres personalizado y 1 pantalla apestosa todavía no funcionaba ... resulta que 1 actividad estaba usando "new MenuInflater" en lugar de getMenuInflater (). ¡Gracias una tonelada!
DiscDev

esto es muy importante. Estaba usando la creación de menuInflater (2 vías). Gracias
wtk

24

Para fragmentos

Los menús con espacio de nombres personalizado evitarán que se muestre showAsAction.

El uso del prefijo "android:" para showAsAction funcionará, aunque Android Studio comentará que debes usar un espacio de nombre personalizado.

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_add_checkin"
          android:title="Add Checkin"
          android:orderInCategory="10"
          android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add"/>
</menu>

Esto está utilizando fragmentos de Android SDK 22 y Support v4, en caso de que eso haga alguna diferencia.


Eso es lo único que resolvió Mi problema (aunque muestra este error). Gracias !
user2630165

3
Puede suprimir el error / advertencia en el diseño XML con las herramientas: ignore = "AppCompatResource" dentro del <item>. Documentos aquí: tools.android.com/tips/lint/suppressing-lint-warnings
Baker

Su respuesta y la de Anton Kizema son las soluciones adecuadas para mí. Y también gracias por el dato tools:ignore.
hata

16

Tengo el mismo problema, pero en Android 5. Tengo 3 elementos, pero el sistema operativo ignoró mi atributo "siempre" y mostró solo 2 elementos. Aquí mi solución:

  @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    Log.d(TAG, "onCreateOptionsMenu()");
    inflater.inflate(R.menu.your_menu, menu);
    for (int j = 0; j < menu.size(); j++) {
        MenuItem item = menu.getItem(j);
        Log.d(TAG, "set flag for " + item.getTitle());
        item.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
    }
}

1
setShowAsActionFlags()requiere API 14, pero esta fue la mejor solución para mí.
Sr. Bungle

6

También asegúrese de tener la ruta correcta para el espacio de nombres. No le dará un mensaje de error si es incorrecto.

yo tenía

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

en vez de

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

Todo lo que sabía era que no estaba funcionando. No estoy seguro de cómo logré olvidar la parte / apk de la ruta, pero sucedió. Sin mensaje de error, solo un error difícil de localizar.


6

En mi caso, tuve que eliminar de la compilación build.gradle de mi aplicación 'com.android.support:appcompat-v7:21.0.3'.

Aviso : Mi min sdk = 14, y el proyecto creado por Android Studio insertó mi dependencia unnesessary.

Después de este reemplazo, puede escribir android: showAsAction = "always"


¡Gracias, me resolvió! En la actualidad, tal vez sea la mejor solución en la mayoría de los casos, porque no es necesario admitir versiones de Android anteriores a la 4.0.
pinyin_samu

Su respuesta y la de Baker son las soluciones adecuadas para mí.
hata

4

Puede que este no sea tu caso, pero estaba usando

new MenuInflater(this).inflate(R.menu.my_menu, menu);

cambiándolo a

getMenuInflater().inflate(R.menu.my_menu, menu);

solucionó el problema!


0
<?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/back"
        android:icon="@drawable/back"
        app:showAsAction="always"
        android:title="@string/back"/>
    <item
        android:id="@id/save"
        android:icon="@drawable/le_top_btn_icon_add"
        app:showAsAction="ifRoom"
        android:title="@string/save"/>
</menu>

no funciona, con supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

ver la "Advertencia"

Debería usar app: showAsAction con la biblioteca appcompat con xmlns: app = "http://schemas.android.com/apk/res-auto" menos ... (Ctrl + F1)

Al usar la biblioteca appcompat, los recursos del menú deben hacer referencia a showAsAction en el espacio de nombres app:, no al espacio de nombres android:.

Del mismo modo, cuando no utilice la biblioteca appcompat, debería utilizar el atributo android: showAsAction.

Creo que la advertencia se puede ignorar.


0

agregue un espacio de nombres personalizado como este para showAsAction y actionViewClass:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
    android:title="@string/search"
    android:icon="@drawable/ic_search"
    app:showAsAction="collapseActionView|ifRoom"
    app:actionViewClass="android.widget.SearchView" />


0

Lo he resuelto reemplazando

android:showAsAction="ifRoom"

con

app:showAsAction="ifRoom"

Ese es el aspecto de menuitme xml,

<item android:id="@+id/action_refresh"
      android:title="Refresh"
      android:icon="@drawable/refresh2"
      app:showAsAction="ifRoom" />

0

La forma más sencilla es modificar su código agregando

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

y cambia este código

android:showAsAction="always"

a

app:showAsAction="always"

y finalmente

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        app:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.