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.

Mcingwe
fuente
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).

Nikola Despotoski
fuente
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>
Mcingwe
fuente
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);
petrnohejl
fuente
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.

Panadero
fuente
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);
    }
}
Lukas
fuente
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.

BeccaP
fuente
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"

Anton Kizema
fuente
¡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!

Bakhshi
fuente
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.

Cuenta
fuente
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" />

Amirouche Zeggagh
fuente
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" />
Haris
fuente
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>
Abdulhakim Zeinu
fuente