Élément de menu Android 4.3 showAsAction = "toujours" ignoré


116

J'utilise la nouvelle bibliothèque appcompat v7 disponible à partir d'Android 4.3 (niveau d'API 18).

Indépendamment de ce qui est spécifié dans showAsAction pour un élément de menu, il n'est pas affiché - il crée toujours l'icône de menu de débordement et place même un seul élément de menu sous le menu.

Essayer d'ajouter un menu à une activité comme celle-ci:

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

Et voici mon menu 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>

Est-ce un bogue de la nouvelle bibliothèque de support v7, ou simplement un problème avec le code? J'ai utilisé le code similaire avec ActionBarSherlock plusieurs fois auparavant.


2
À des fins d'information - "... "always"n'est pas recommandé; il est préférable d'utiliser "ifRoom"et de laisser le système d'exploitation décider."
ChiefTwoPencils

Réponses:


313

Il vous manque probablement l'espace de noms requis:

<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>

Remplacez-le [yourapp]par le nom de votre application ou tout autre espace de noms que votre cœur désire partout.

Autres choses à vérifier:

  • Voir si votre classe d'activité s'étend ActionBarActivity

Vérifiez si le problème persiste.


Documentation de référence Android: Ajout de boutons d'action . Voici le texte pertinent:

Si votre application utilise la bibliothèque de support pour la compatibilité sur des versions aussi basses qu'Android 2.1, l'attribut showAsAction n'est pas disponible à partir de l'espace de noms android:. Au lieu de cela, cet attribut est fourni par la bibliothèque de support et vous devez définir votre propre espace de noms XML et utiliser cet espace de noms comme préfixe d'attribut. (Un espace de noms XML personnalisé doit être basé sur le nom de votre application, mais il peut s'agir de n'importe quel nom de votre choix et n'est accessible que dans la portée du fichier dans lequel vous le déclarez.)


2
C'est aussi ce que j'ai découvert. Merci - certainement accepté. Mais showAsAction doit utiliser cet espace de noms personnalisé.
Mcingwe

5
'yourapp' signifie dans String.xml <string name = "app_name"> yourapp </string> n'est-ce pas?
LOG_TAG

4
Quelqu'un peut-il expliquer POURQUOI cela fonctionne? Pourquoi est-il nécessaire d'étendre un espace de noms personnalisé? Peu confus.
Dineth

8
@dineth appcompat est utilisé comme projet de bibliothèque. Cela signifie que toutes ses ressources (chaînes, dessinables, attributs ...) sont déclarées dans l'espace de noms de votre application au lieu de l'espace de noms android. Comme l' showAsActionattribut n'existait pas dans Android-7, vous devez utiliser l'espace de noms de votre application
Nicopico

22
Tout le monde dit «espace de noms personnalisé» ou «espace de noms correspondant à votre application». Mais l'espace de noms est toujours http://schemas.android.com/apk/res-autodans chaque exemple. Ce n'est pas personnalisé ou correspondant à votre application. C'est l'espace de noms réel de la documentation. Je pense que tout le monde veut dire un préfixe personnalisé , et il peut en fait être ce que vous voulez. Est-ce vrai?
Andrew Arnott

52

J'ai compris. Avec la bibliothèque de support v7, showAsAction devrait passer sous un espace de noms personnalisé comme celui-ci:

<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' signifie dans String.xml "<string name =" app_name "> balloonberry </string>" n'est-ce pas?
LOG_TAG

5
@LOG_TAG - non, il devrait être comme indiqué ci-dessus. Ce n'est pas une chaîne, mais un espace de noms.
BeccaP

ohhh support v7 errr ... c'est ok sur support v4
Yasitha Waduge

Merci pour l'explication Mcingwe
Sachidananda Naik

32

Assurez-vous également que vous utilisez le gonfleur correct dans la méthode ActionBarActivity.onCreateOptionsMenu ().

Solution correcte:

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

Solution incorrecte:

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

1
J'ai passé toutes les réponses ci-dessus et une autre réponse sur stackoverflow, mais la seule chose qui me manquait est votre réponse - getMenuInflater (). Merci d'avoir partagé ça.
Amt87

Merci BEAUCOUP pour celui-ci. J'ai converti tous mes plus de 100 menus pour utiliser un espace de noms personnalisé et 1 écran puant ne fonctionnait toujours pas ... il s'avère qu'une activité utilisait "new MenuInflater" au lieu de getMenuInflater (). Merci beaucoup!
DiscDev

c'est très important. J'utilisais la création menuInflater (2 voies). Merci
wtk

24

Pour les fragments

Les menus avec un espace de nom personnalisé empêcheront showAsAction de s'afficher.

L'utilisation du préfixe "android:" pour showAsAction fonctionnera, même si Android Studio vous remarquera devez utiliser un espace de nom personnalisé.

<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>

Cela utilise les fragments Android SDK 22 et Support v4, au cas où cela ferait une différence.


C'est la seule chose qui a résolu mon problème (bien qu'il montre cette erreur). Merci !
user2630165

3
Vous pouvez supprimer l'erreur / l'avertissement dans la mise en page XML avec les outils: ignore = "AppCompatResource" dans le <item>. Docs ici: tools.android.com/tips/lint/suppressing-lint-warnings
Baker

Votre réponse et celle d'Anton Kizema sont les bonnes solutions pour moi. Et aussi merci pour le tuyau tools:ignore.
hata

16

J'ai eu le même problème, mais sur Android 5. J'ai 3 éléments mais le système d'exploitation a ignoré mon attribut "toujours" et n'a montré que 2 éléments. Voici ma solution:

  @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()nécessite l'API 14, mais c'était toujours la meilleure solution pour moi.
Mr.Bungle

6

Assurez-vous également que vous disposez du chemin d'accès correct pour l'espace de noms. Il ne vous donnera pas de message d'erreur si c'est faux.

j'ai eu

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

au lieu de

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

Tout ce que je savais, c'est que cela ne fonctionnait pas. Je ne sais pas comment j'ai réussi à oublier la partie / apk du chemin, mais c'est arrivé. Aucun message d'erreur, juste un bug insaisissable à traquer.


6

Dans mon cas, j'ai dû supprimer de la compilation build.gradle de mon application 'com.android.support:appcompat-v7:21.0.3'.

Remarquer : Mon sdk min = 14 et le projet créé par Android Studio ont inséré ma dépendance inutile.

Après ce remplacement, vous pouvez écrire android: showAsAction = "always"


Merci, cela m'a résolu! De nos jours, c'est peut-être la meilleure solution dans la plupart des cas, car il n'est pas nécessaire de prendre en charge les versions d'Android antérieures à 4.0.
pinyin_samu

Votre réponse et celle de Baker sont les bonnes solutions pour moi.
hata

4

Ce n'est peut-être pas votre cas mais j'utilisais

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

le changer en

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

résolu le problème!


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>

ne fonctionne pas, avec supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

voir le "Avertissement"

Doit utiliser app: showAsAction avec la bibliothèque appcompat avec xmlns: app = "http://schemas.android.com/apk/res-auto" less ... (Ctrl + F1)

Lorsque vous utilisez la bibliothèque appcompat, les ressources du menu doivent faire référence à showAsAction dans l'espace de noms app:, et non à l'espace de noms android:.

De même, lorsque vous n'utilisez pas la bibliothèque appcompat, vous devez utiliser l'attribut android: showAsAction.

Je pense que l'avertissement peut être ignoré.


0

ajoutez un espace de noms personnalisé comme celui-ci à showAsAction et 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

Je l'ai résolu en remplaçant

android:showAsAction="ifRoom"

avec

app:showAsAction="ifRoom"

Cela ressemble à menuitme xml,

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

0

Le moyen le plus simple est de modifier votre code en ajoutant

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

et changez ce code

android:showAsAction="always"

à

app:showAsAction="always"

et enfin

<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>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.