Android 4.3 Menüpunkt showAsAction = "immer" ignoriert

116

Ich verwende die neue v7-Appcompat-Bibliothek, die ab Android 4.3 (API-Level 18) verfügbar ist.

Unabhängig davon, was in showAsAction für einen Menüpunkt angegeben ist, wird er nicht angezeigt. Er erstellt immer das Überlaufmenüsymbol und fügt sogar einen einzelnen Menüpunkt unter das Menü ein.

Der Versuch, einer Aktivität wie dieser ein Menü hinzuzufügen:

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

Und hier ist mein 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>

Ist es ein Fehler der neuen Support-Bibliothek v7 oder nur etwas falsch mit dem Code? Ich habe den ähnlichen Code schon oft mit ActionBarSherlock verwendet.

Mcingwe
quelle
2
Zu Informationszwecken - "... "always"wird nicht empfohlen; es ist besser "ifRoom", das Betriebssystem zu verwenden und es entscheiden zu lassen."
ChiefTwoPencils

Antworten:

313

Wahrscheinlich fehlt Ihnen der erforderliche Namespace:

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

Ersetzen Sie [yourapp]durch Ihren App-Namen oder einen beliebigen Namespace, den Ihr Herz überall wünscht.

Andere Dinge, die es wert sind, überprüft zu werden:

  • Überprüfen Sie, ob Ihre Aktivitätsklasse erweitert wird ActionBarActivity

Überprüfen Sie, ob das Problem weiterhin besteht.


Android-Referenzdokumentation: Hinzufügen von Aktionsschaltflächen . Hier ist der relevante Text:

Wenn Ihre App die Support-Bibliothek aus Kompatibilitätsgründen mit Versionen ab Android 2.1 verwendet, ist das Attribut showAsAction im Android: Namespace nicht verfügbar. Stattdessen wird dieses Attribut von der Support-Bibliothek bereitgestellt. Sie müssen Ihren eigenen XML-Namespace definieren und diesen Namespace als Attributpräfix verwenden. (Ein benutzerdefinierter XML-Namespace sollte auf Ihrem App-Namen basieren. Er kann jedoch ein beliebiger Name sein und ist nur im Rahmen der Datei zugänglich, in der Sie ihn deklarieren.)

Nikola Despotoski
quelle
2
Das habe ich auch herausgefunden. Danke - auf jeden Fall akzeptiert. Die showAsAction sollte jedoch diesen benutzerdefinierten Namespace verwenden.
Mcingwe
5
'yourapp' bedeutet in String.xml <string name = "app_name"> yourapp </ string> richtig?
LOG_TAG
4
Kann jemand erklären, warum das funktioniert? Warum muss ein benutzerdefinierter Namespace erweitert werden? Wenig verwirrt.
Dineth
8
@dineth appcompat wird als Bibliotheksprojekt verwendet. Dies bedeutet, dass alle Ressourcen (Zeichenfolgen, Zeichenbarkeit, Attribute ...) in Ihrem Anwendungsnamespace anstelle des Android-Namespace deklariert werden. Da das showAsActionAttribut in Android-7 nicht vorhanden war, müssen Sie Ihren App-Namespace verwenden
nicopico
22
Jeder sagt "benutzerdefinierter Namespace" oder "ein Namespace, der zu Ihrer App passt". Aber der Namespace ist immer http://schemas.android.com/apk/res-autoin jedem Beispiel. Dies ist keine benutzerdefinierte oder eine App, die zu Ihrer App passt. Das ist der eigentliche Namespace aus der Dokumentation. Ich denke, jeder meint ein benutzerdefiniertes Präfix , und es kann tatsächlich sein, was immer Sie wollen. Ist das wahr?
Andrew Arnott
52

Ich habe es selbst herausgefunden. Mit der Support-Bibliothek v7 sollte showAsAction unter einem benutzerdefinierten Namespace wie folgt abgelegt werden:

<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
quelle
1
'balloonberry' bedeutet in String.xml "<string name =" app_name "> balloonberry </ string>", oder?
LOG_TAG
5
@LOG_TAG - nein, es sollte genauso sein wie oben eingegeben. Dies ist keine Zeichenfolge, sondern ein Namespace.
BeccaP
ohhh support v7 errr ... es ist ok auf support v4
Yasitha Waduge
Vielen Dank für die Erklärung Mcingwe
Sachidananda Naik
32

Stellen Sie außerdem sicher, dass Sie in der ActionBarActivity.onCreateOptionsMenu () -Methode den richtigen Inflater verwenden.

Richtige Lösung:

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

Falsche Lösung:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);
petrnohejl
quelle
1
Ich habe alle oben genannten Antworten und weitere Antworten zum Stackoverflow übergeben, aber das einzige, was mir gefehlt hat, ist Ihre Antwort - getMenuInflater (). Vielen Dank für das Teilen.
Amt87
Vielen Dank für diesen einen. Ich habe alle meine über 100 Menüs so konvertiert, dass sie einen benutzerdefinierten Namespace verwenden, und 1 stinkender Bildschirm funktionierte immer noch nicht. Es stellte sich heraus, dass 1 Aktivität "new MenuInflater" anstelle von getMenuInflater () verwendete. Danke vielmals!
DiscDev
Dies ist sehr wichtig. Ich habe die menuInflater-Erstellung (2-Wege) verwendet. Danke
wtk
24

Für Fragmente

Menüs mit benutzerdefiniertem Namespace verhindern, dass showAsAction angezeigt wird.

Mit „android:“ Präfix für showAsAction funktionieren wird, obwohl Android Studio wird bemerken Sie sollten einen benutzerdefinierten Namen Raum verwenden.

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

Hierbei werden Fragmente von Android SDK 22 und Support v4 verwendet, falls dies einen Unterschied macht.

Bäcker
quelle
Das ist das einzige, was Mein Problem gelöst hat (obwohl es diesen Fehler zeigt). Vielen Dank !
user2630165
3
Sie können den Fehler / die Warnung im XML-Layout mit den folgenden Tools unterdrücken: ignore = "AppCompatResource" im <item>. Dokumente
Baker
Ihre Antwort und die von Anton Kizema sind die richtigen Lösungen für mich. Und auch danke für den Tipp tools:ignore.
Hata
16

Ich habe das gleiche Problem, aber unter Android 5. Ich habe 3 Elemente, aber das Betriebssystem hat mein Attribut "immer" ignoriert und nur 2 Elemente angezeigt. Hier meine Lösung:

  @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
quelle
1
setShowAsActionFlags()erfordert API 14, aber dies war immer noch die beste Lösung für mich.
Mr. Bungle
6

Stellen Sie außerdem sicher, dass Sie den richtigen Pfad für den Namespace haben. Es wird keine Fehlermeldung angezeigt, wenn es falsch ist.

ich hatte

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

anstatt

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

Ich wusste nur, dass es nicht funktionierte. Ich bin mir nicht sicher, wie ich den / apk-Teil des Pfades vergessen habe, aber es ist passiert. Keine Fehlermeldung, nur ein schwer fassbarer Fehler.

BeccaP
quelle
6

In meinem Fall musste ich aus der build.gradle-Kompilierung meiner App 'com.android.support:appcompat-v7:21.0.3' entfernen.

Hinweis : My min sdk = 14, und erstelltes Projekt von Android Studio eingefügt meine unnesessary dependancy.

Nach diesem Ersetzen können Sie android schreiben: showAsAction = "immer"

Anton Kizema
quelle
Danke, es hat mich gelöst! Heutzutage ist es in den meisten Fällen vielleicht die beste Lösung, da Android-Versionen vor 4.0 nicht unterstützt werden müssen.
pinyin_samu
Ihre Antwort und Baker's sind die richtigen Lösungen für mich.
Hata
4

Dies ist möglicherweise nicht Ihr Fall, aber ich habe verwendet

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

Ändern in

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

Das Problem wurde behoben!

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

funktioniert nicht mit supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

siehe die "Warnung"

Sollte app: showAsAction mit der Appcompat-Bibliothek mit xmlns verwenden: app = "http://schemas.android.com/apk/res-auto" weniger ... (Strg + F1)

Bei Verwendung der Appcompat-Bibliothek sollten sich die Menüressourcen auf die showAsAction im App: Namespace beziehen, nicht auf den Android: Namespace.

Wenn Sie die Appcompat-Bibliothek nicht verwenden, sollten Sie auch das Attribut android: showAsAction verwenden.

Ich denke, die Warnung kann ignoriert werden.

Rechnung
quelle
0

Fügen Sie showAsAction und actionViewClass einen solchen benutzerdefinierten Namespace hinzu:

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

Ich habe es durch Ersetzen gelöst

android:showAsAction="ifRoom"

mit

app:showAsAction="ifRoom"

Das ist menuitme xml aussehen,

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

Am einfachsten ist es, den Code durch Hinzufügen zu ändern

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

und ändern Sie diesen Code

android:showAsAction="always"

zu

app:showAsAction="always"

und schlussendlich

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