Pozycja menu systemu Android 4.3 showAsAction = „zawsze” ignorowana

116

Używam nowej biblioteki appcompat w wersji 7, dostępnej od Androida 4.3 (poziom API 18).

Niezależnie od tego, co jest określone w showAsAction dla elementu menu, nie jest ono wyświetlane - zawsze tworzy ikonę menu przepełnienia i umieszcza nawet pojedynczy element menu pod menu.

Próbuję dodać menu do takiej czynności:

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

A oto moje 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>

Czy to błąd nowej biblioteki wsparcia v7, czy po prostu coś nie tak z kodem? Wiele razy używałem podobnego kodu w ActionBarSherlock.

Mcingwe
źródło
2
W celach informacyjnych - „... "always"nie jest zalecane; lepiej jest użyć "ifRoom"i pozwolić systemowi operacyjnemu zdecydować”.
ChiefTwoPencils

Odpowiedzi:

313

Prawdopodobnie brakuje wymaganej przestrzeni nazw:

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

Zastąp [yourapp]nazwę swojej aplikacji lub dowolną przestrzenią nazw, której dusza zapragnie.

Inne rzeczy warte sprawdzenia:

  • Sprawdź, czy Twoja klasa aktywności się wydłuża ActionBarActivity

Sprawdź, czy problem nadal występuje.


Dokumentacja referencyjna systemu Android: Dodawanie przycisków akcji . Oto odpowiedni tekst:

Jeśli Twoja aplikacja korzysta z biblioteki pomocy technicznej w celu zapewnienia zgodności w wersjach tak niskich, jak Android 2.1, atrybut showAsAction nie jest dostępny w obszarze nazw android:. Zamiast tego ten atrybut jest udostępniany przez bibliotekę obsługi i należy zdefiniować własną przestrzeń nazw XML i użyć tej przestrzeni nazw jako prefiksu atrybutu. (Niestandardowa przestrzeń nazw XML powinna być oparta na nazwie aplikacji, ale może to być dowolna nazwa i jest dostępna tylko w zakresie pliku, w którym ją zadeklarowałeś).

Nikola Despotoski
źródło
2
Tego też się dowiedziałem. Dziękuję - zdecydowanie przyjęty. Ale showAsAction powinno używać tej niestandardowej przestrzeni nazw.
Mcingwe,
5
„yourapp” oznacza w String.xml <string name = "app_name"> twojaaplikacja </string>, prawda?
LOG_TAG
4
Czy ktoś może wyjaśnić, DLACZEGO to działa? Dlaczego istnieje potrzeba rozszerzenia niestandardowej przestrzeni nazw? Trochę zdezorientowany.
obiad
8
@dineth appcompat jest używany jako projekt biblioteki. Oznacza to, że wszystkie jego zasoby (ciągi znaków, możliwe do rysowania, atrybuty ...) są zadeklarowane w przestrzeni nazw aplikacji zamiast w przestrzeni nazw systemu Android. Ponieważ showAsActionatrybut nie istniał w systemie Android-7, musisz użyć przestrzeni nazw aplikacji
nicopico
22
Wszyscy mówią „niestandardowa przestrzeń nazw” lub „przestrzeń nazw pasująca do Twojej aplikacji”. Ale przestrzeń nazw jest zawsze http://schemas.android.com/apk/res-autow każdym przykładzie. To nie jest niestandardowy ani taki, który pasuje do Twojej aplikacji. To jest rzeczywista przestrzeń nazw z dokumentacji. Myślę, że każdy ma na myśli niestandardowy prefiks , a właściwie może to być cokolwiek chcesz. Czy to prawda?
Andrew Arnott,
52

Zrozumiałem. Dzięki bibliotece wsparcia v7 showAsAction powinno znajdować się w niestandardowej przestrzeni nazw, takiej jak ta:

<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
źródło
1
„balonik” oznacza w String.xml „<string name =" app_name "> balonik </string>", prawda?
LOG_TAG
5
@LOG_TAG - nie, powinno być tak, jak podano powyżej. To nie jest ciąg, ale przestrzeń nazw.
BeccaP
ohhh wsparcie v7 errr ... jest ok na wsparcie v4
Yasitha Waduge
Dzięki za wyjaśnienie Mcingwe
Sachidananda Naik
32

Upewnij się również, że używasz prawidłowego inflatera w metodzie ActionBarActivity.onCreateOptionsMenu ().

Prawidłowe rozwiązanie:

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

Nieprawidłowe rozwiązanie:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);
petrnohejl
źródło
1
Zdałem wszystkie powyższe odpowiedzi i kolejne odpowiedzi na stackoverflow, ale jedyne czego mi brakowało to Twoja odpowiedź - getMenuInflater (). Dzięki za udostępnienie tego.
Amt87
Dziękuję bardzo za ten. Przekonwertowałem wszystkie moje ponad 100 menu, aby używały niestandardowej przestrzeni nazw, a 1 śmierdzący ekran nadal nie działał ... okazuje się, że 1 aktywność używała „nowego MenuInflater” zamiast getMenuInflater (). Wielkie dzięki!
DiscDev
to jest bardzo ważne. Używałem menuInflater create (2 sposoby). Dzięki
wtk
24

Dla fragmentów

Menu z niestandardową przestrzenią nazw zapobiegną wyświetlaniu showAsAction.

Używanie prefiksu „android:” dla showAsAction zadziała, mimo że Android Studio zauważy, że należy użyć niestandardowej przestrzeni nazw.

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

Używa to Android SDK 22 i fragmentów Support v4, na wypadek gdyby miało to jakiekolwiek znaczenie.

Piekarz
źródło
To jedyna rzecz, która rozwiązała mój problem (chociaż pokazuje ten błąd). Dzięki !
user2630165
3
Możesz pominąć błąd / ostrzeżenie w układzie XML za pomocą narzędzi: ignore = "AppCompatResource" w <item>. Dokumenty tutaj: tools.android.com/tips/lint/suppressing-lint-warnings
Baker
Twoja odpowiedź i Anton Kizema są dla mnie odpowiednimi rozwiązaniami. A także dzięki za wskazówkę tools:ignore.
hata
16

Mam ten sam problem, ale na Androidzie 5. Mam 3 pozycje, ale system operacyjny zignorował mój atrybut „zawsze” i pokazał tylko 2 pozycje. Oto moje rozwiązanie:

  @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
źródło
1
setShowAsActionFlags()wymaga API 14, ale nadal było to dla mnie najlepsze rozwiązanie.
Mr. Bungle,
6

Upewnij się również, że masz poprawną ścieżkę do przestrzeni nazw. Nie wyświetli komunikatu o błędzie, jeśli jest źle.

miałem

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

zamiast

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

Wiedziałem tylko, że to nie działa. Nie jestem pewien, jak udało mi się zapomnieć o części ścieżki / apk, ale tak się stało. Brak komunikatu o błędzie, tylko nieuchwytny błąd do wyśledzenia.

BeccaP
źródło
6

W moim przypadku musiałem usunąć z kompilacji build.gradle mojej aplikacji „com.android.support:appcompat-v7:21.0.3”.

Uwaga : Moje min sdk = 14 i utworzony projekt przez studio android wstawił moją niepotrzebną zależność.

Po tej zamianie możesz napisać android: showAsAction = "zawsze"

Anton Kizema
źródło
Dzięki, że mnie rozwiązało! W dzisiejszych czasach może to być najlepsze rozwiązanie w większości przypadków, ponieważ nie jest konieczne wspieranie wersji Androida przed 4.0.
pinyin_samu
Twoja odpowiedź i Baker's to dla mnie właściwe rozwiązania.
hata
4

To może nie być twój przypadek, ale używałem

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

zmiana na

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

naprawiono problem!

Bakhshi
źródło
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>

nie działa, z supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

zobacz „Ostrzeżenie”

Powinien używać app: showAsAction z biblioteką appcompat z xmlns: app = "http://schemas.android.com/apk/res-auto" mniej ... (Ctrl + F1)

Korzystając z biblioteki appcompat, zasoby menu powinny odnosić się do showAsAction w app: namespace, a nie do android: namespace.

Podobnie, gdy nie używasz biblioteki appcompat, powinieneś używać atrybutu android: showAsAction.

Myślę, że ostrzeżenie można zignorować.

Rachunek
źródło
0

dodaj niestandardową przestrzeń nazw, taką jak ta, aby showAsAction i 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
źródło
0

Rozwiązałem to, zastępując

android:showAsAction="ifRoom"

z

app:showAsAction="ifRoom"

Tak wygląda menuitme xml,

<item android:id="@+id/action_refresh"
      android:title="Refresh"
      android:icon="@drawable/refresh2"
      app:showAsAction="ifRoom" />
Haris
źródło
0

Najprostszym sposobem jest zmodyfikowanie kodu poprzez dodanie

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

i zmień ten kod

android:showAsAction="always"

do

app:showAsAction="always"

i w końcu

<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
źródło