Voce di menu Android 4.3 showAsAction = "sempre" ignorata


116

Sto utilizzando la nuova libreria appcompat v7 disponibile a partire da Android 4.3 (livello API 18).

Indipendentemente da quanto specificato in showAsAction per una voce di menu, non viene mostrato: crea sempre l'icona del menu di overflow e mette anche una singola voce di menu sotto il menu.

Tentativo di aggiungere un menu a un'attività come questa:

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

Ed ecco il mio 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>

È un bug della nuova libreria di supporto v7 o semplicemente qualcosa di sbagliato nel codice? Ho già utilizzato molte volte il codice simile con ActionBarSherlock.


2
A scopo informativo - "... "always"non è raccomandato; è meglio usare "ifRoom"e lasciare che sia il sistema operativo a decidere."
ChiefTwoPencil

Risposte:


313

Probabilmente ti manca lo spazio dei nomi richiesto:

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

Sostituisci [yourapp]con il nome della tua app o qualsiasi spazio dei nomi che il tuo cuore desidera ovunque.

Altre cose che vale la pena controllare:

  • Verifica se la tua classe di attività si estende ActionBarActivity

Controlla se il problema persiste.


Documentazione di riferimento Android: aggiunta di pulsanti di azione . Ecco il testo pertinente:

Se la tua app utilizza la libreria di supporto per la compatibilità su versioni a partire da Android 2.1, l'attributo showAsAction non è disponibile nello spazio dei nomi android:. Questo attributo viene invece fornito dalla libreria di supporto ed è necessario definire il proprio spazio dei nomi XML e utilizzare tale spazio dei nomi come prefisso dell'attributo. (Uno spazio dei nomi XML personalizzato dovrebbe essere basato sul nome della tua app, ma può essere qualsiasi nome tu voglia ed è accessibile solo nell'ambito del file in cui lo dichiari.)


2
Anche questo è quello che ho scoperto. Grazie - decisamente accettato. Ma showAsAction dovrebbe usare quello spazio dei nomi personalizzato.
Mcingwe

5
"yourapp" significa in String.xml <string name = "app_name"> yourapp </string> giusto?
LOG_TAG

4
Qualcuno può spiegare PERCHÉ funziona? Perché è necessario estendere uno spazio dei nomi personalizzato? Un po 'confuso.
Dineth

8
@dineth appcompat viene utilizzato come progetto di libreria. Ciò significa che tutte le sue risorse (stringhe, disegnabili, attributi ...) sono dichiarate nello spazio dei nomi dell'applicazione anziché nello spazio dei nomi Android. Poiché l' showAsActionattributo non esisteva in Android-7, devi usare lo spazio dei nomi della tua app
nicopico

22
Tutti dicono "spazio dei nomi personalizzato" o "uno spazio dei nomi che corrisponde alla tua app". Ma lo spazio dei nomi è sempre http://schemas.android.com/apk/res-autoin ogni esempio. Non è personalizzato o che corrisponde alla tua app. Questo è lo spazio dei nomi effettivo dalla documentazione. Penso che tutti intendano un prefisso personalizzato e può effettivamente essere quello che vuoi. È vero?
Andrew Arnott

52

L'ho capito da solo. Con la libreria di supporto v7, showAsAction dovrebbe andare sotto uno spazio dei nomi personalizzato come questo:

<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 in String.xml "<string name =" app_name "> balloonberry </string>" giusto?
LOG_TAG

5
@LOG_TAG - no, dovrebbe essere solo come inserito sopra. Questa non è una stringa, ma uno spazio dei nomi.
BeccaP

ohhh supporto v7 errr ... va bene il supporto v4
Yasitha Waduge

Grazie per la spiegazione Mcingwe
Sachidananda Naik

32

Assicurati inoltre di utilizzare il valore di gonfiaggio corretto nel metodo ActionBarActivity.onCreateOptionsMenu ().

Soluzione corretta:

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

Soluzione errata:

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

1
Ho passato tutte le risposte di cui sopra e un'altra risposta su stackoverflow, ma l'unica cosa che mi mancava è che tu risponda - getMenuInflater (). Grazie per aver condiviso questo.
Amt87

Grazie mille per questo. Ho convertito tutti i miei oltre 100 menu per utilizzare uno spazio dei nomi personalizzato e 1 schermo puzzolente non funzionava ancora ... risulta che 1 attività utilizzava "new MenuInflater" invece di getMenuInflater (). Grazie mille!
DiscDev

questo è molto importante. Stavo usando la creazione menuInflater (2 vie). Grazie
wtk

24

Per frammenti

I menu con spazio dei nomi personalizzato impediranno la visualizzazione di showAsAction.

L'utilizzo del prefisso "android:" per showAsAction funzionerà, anche se Android Studio indicherà che dovresti utilizzare uno spazio dei nomi personalizzato.

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

Questo utilizza Android SDK 22 e frammenti di supporto v4, nel caso in cui ciò faccia la differenza.


Questa è l'unica cosa che ha risolto il mio problema (anche se mostra questo errore). Grazie !
user2630165

3
È possibile eliminare l'errore / avviso nel layout XML con gli strumenti: ignore = "AppCompatResource" all'interno di <item>. Documenti qui: tools.android.com/tips/lint/suppressing-lint-warnings
Baker

La tua risposta e quella di Anton Kizema sono la soluzione giusta per me. E grazie anche per il suggerimento tools:ignore.
hata

16

Ho lo stesso problema, ma su Android 5. Ho 3 articoli ma il sistema operativo ha ignorato il mio attributo "sempre" e ha mostrato solo 2 articoli. Ecco la mia soluzione:

  @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()richiede API 14, ma questa era ancora la soluzione migliore per me.
Mr. Bungle

6

Assicurati inoltre di avere il percorso corretto per lo spazio dei nomi. Non ti darà un messaggio di errore se è sbagliato.

avevo

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

invece di

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

Tutto quello che sapevo era che non funzionava. Non sono sicuro di come sono riuscito a dimenticare la parte / apk del percorso, ma è successo. Nessun messaggio di errore, solo un bug sfuggente da rintracciare.


6

Nel mio caso, ho dovuto rimuovere dalla compilazione build.gradle della mia app "com.android.support:appcompat-v7:21.0.3".

Avviso : il mio min sdk = 14 e il progetto creato da Android Studio hanno inserito la mia dipendenza non necessaria.

Dopo questa sostituzione puoi scrivere android: showAsAction = "sempre"


Grazie mi ha risolto! Oggi è forse la soluzione migliore nella maggior parte dei casi, perché non è necessario supportare le versioni di Android precedenti alla 4.0.
pinyin_samu

La tua risposta e quella di Baker sono la soluzione giusta per me.
hata

4

Questo potrebbe non essere il tuo caso, ma stavo usando

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

cambiandolo in

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

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

non funziona, con supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

vedere "Avviso"

Dovrebbe usare app: showAsAction con la libreria appcompat con xmlns: app = "http://schemas.android.com/apk/res-auto" less ... (Ctrl + F1)

Quando si utilizza la libreria appcompat, le risorse del menu devono fare riferimento a showAsAction nello spazio dei nomi app:, non nello spazio dei nomi android:.

Allo stesso modo, quando non usi la libreria appcompat, dovresti usare l'attributo android: showAsAction.

Penso che l'avviso possa essere ignorato.


0

aggiungi uno spazio dei nomi personalizzato come questo a showAsAction e 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

L'ho risolto sostituendo

android:showAsAction="ifRoom"

con

app:showAsAction="ifRoom"

Questo è l' aspetto di menuitme xml,

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

0

Il modo più semplice è modificare il codice aggiungendo

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

e cambia questo codice

android:showAsAction="always"

per

app:showAsAction="always"

e infine

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.