Pasek działań Androida nie pokazuje przepełnienia

90

W mojej aplikacji mam pasek akcji z 3 elementami.

Ze względu na problemy z przestrzenią można wyświetlić tylko 2, więc spodziewałbym się, że pierwsza zostanie wyświetlona, ​​a reszta zostanie wyświetlona w przepełnieniu. Jednak w praktyce wyświetlane są tylko pierwsze 2 pozycje i nie można wykryć przepełnienia.

Oto odpowiedni kod: list_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_insert"
    android:icon="@android:drawable/ic_menu_add"
    android:title="@string/menu_insert" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_call"
    android:icon="@android:drawable/ic_menu_call"
    android:title="@string/menu_call" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_agenda"
    android:icon="@android:drawable/ic_menu_agenda"
    android:title="@string/menu_agenda" 
    android:showAsAction="ifRoom|withText"/>
</menu>

Activity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater mi = getMenuInflater();
    mi.inflate(R.menu.list_menu, menu);
    return true;
}
Mats Raemen
źródło
120
Jeśli Twoje urządzenie ma przycisk menu, ikona przepełnienia nie będzie wyświetlana. Na jakim urządzeniu jesteś?
Reinier
1
urządzenie wirtualne, na którym testuję, ma rzeczywiście przycisk menu, kliknąłem go i pojawił się brakujący element, dzięki!
Mats Raemen
2
@Reinier Używam ActionBarSherlock. Na Galaxy Ace z systemem 2.3 jest to pokazane, w Galaxy SII z systemem 4.0 nie jest pokazane. Oba mają przycisk menu HW.
Mister Smith
2
Chciałem potwierdzić, że zdziwiło mnie to, że mam ikonę przepełnienia na zakupie Nexusa 7, a nie na Galaxy Note II. Notatka miała przycisk menu. Dzięki!
bsautner
@Reinier proszę o pomoc w obliczu tego samego problemu, co powinienem zrobić?
rupesh

Odpowiedzi:

125

Jeśli chcesz pokazać trzy kropki, niezależnie od przycisku menu urządzenia! możesz wywołać tę metodę w swojej klasie aplikacji 'onCreate method-

private void makeActionOverflowMenuShown() {
    //devices with hardware menu button (e.g. Samsung Note) don't show action overflow menu
    try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if (menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage());
    }
}
Atul Kaushik
źródło
32
To okropny hack, który narusza spójność z pozostałymi aplikacjami na platformie. Nie rób tego.
adamp
19
Wydaje się, że to mniejsze zło. Obecne zachowanie jest niedopuszczalne.
biorbnA
6
To świetny sposób na przepełnienie, klawisz menu nie powinien być już tolerowany.
Necronet
5
Działa świetnie! Działa nawet, jeśli użytkownik naciśnie przycisk menu sprzętowego (co jest genialne), chociaż dwukrotnie usłyszysz efekt dźwiękowy menu ... czy ktoś wie, jak sprawić, by zabrzmiało tylko raz?
Bruce
5
TO NIE JEST HACK. Twórcy muszą wiedzieć, jak nazywać hacki, ponieważ w Androidzie nie jest to po prostu 2 + 2. Refleksja oszczędza czas dzięki mechanizmom Java, w przeciwnym razie przekazywałbyś konteksty do swoich klas wewnętrznych 24/7 lub dostosowywał AOSP do nieskończoności. Dla mnie to rozwiązanie rozwiązuje problem konieczności zastąpienia i uwzględnienia mnóstwa niestandardowych treści AOSP ORAZ powiązanych, prywatnych skojarzeń tylko ze względu na to, co puryści uważają za czyste. Czy wiesz, że nie możesz wymusić konsekwentnego włączenia FASTSCROLL dla małych list? Zanim użyłem refleksji, wymagało to ode mnie skopiowania ponad 10 zasobów AOSP w celu edycji JEDNEGO znaku.
leRobot
53

Pasek akcji

res / menu / menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- Search / will display always -->
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="always"
        android:title="@string/action_search"/>

    <!-- Location Found -->
    <item
        android:id="@+id/action_location_found"
        android:icon="@drawable/ic_action_location_found"
        android:showAsAction="always"
        android:title="@string/action_location_found"/>

    <!-- More -->
    <item
        android:id="@+id/a_More"
        android:icon="@drawable/ic_action_overflow"
        android:showAsAction="always"
        android:title="More">
        <menu>

            <!-- Refresh -->
            <item
                android:id="@+id/action_refresh"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_refresh"/>

            <!-- Help -->
            <item
                android:id="@+id/action_help"
                android:icon="@drawable/ic_action_help"
                android:showAsAction="never"
                android:title="@string/action_help"/>

            <!-- Check updates -->
            <item
                android:id="@+id/action_check_updates"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_check_updates"/>
        </menu>
    </item>

</menu>

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

}

Pobierz zestaw ikon paska akcji

Kirit Vaghela
źródło
2
Spójrz na komentarz @Reinier, to prawda: „Jeśli Twoje urządzenie ma przycisk menu, ikona przepełnienia się nie pojawi”.
Ahmad Dwaik „Warlock”
Testuję na urządzeniu, które ma przycisk menu i przepełnienie jest widoczne w moim przypadku. Używam android:showAsAction="always"do większej ilości pozycji
Kirit Vaghela,
na jakim urządzeniu to przetestowałeś? Użyłem Neo V Xperia i S #
Ahmad Dwaik 'Warlock'
1
Uwaga: przedmiot, który zawyża twoje przepełnione menu, MUSI pokazaćAsAction = "zawsze"
Kirit Vaghela,
1
Funkcja showAsAction nie jest dostępna w przestrzeni nazw systemu Android w starszych zestawach SDK. Aby temu zaradzić, skorzystaj z tego linku developer.android.com/training/basics/actionbar/ . Po dodaniu tego NS schemas.android.com/apk/res-auto powyższa sztuczka zadziałała idealnie dla mnie
chedine
42

Zdaję sobie sprawę, że to nie jest przepełnione menu, ale jest podobne. OK, to jest proste, ale trudno było to rozgryźć.

Najpierw potrzebujesz pozycji menu, której chcesz użyć jako inflatora przepełnienia. Przykład

<item
        android:id="@+id/a_More"
        android:icon="@drawable/more"
        android:showAsAction="always"
        android:title="More">
        </item>

Gdy masz już element, dodaj podmenu zawierające żądane elementy w rozszerzonym menu. Przykład:

<item
    android:id="@+id/a_More"
    android:icon="@drawable/more"
    android:showAsAction="always"
    android:title="More">
    <menu>
        <item
            android:id="@+id/aM_Home"
            android:icon="@drawable/home"
            android:title="Home"/>
    </menu>
</item>

Po kliknięciu spowoduje to nadmuchanie innych przedmiotów w ciągu. Moja aplikacja korzysta z ActionBarSherlock 4.0, więc zanim to zadziała, musisz uzyskać dostęp do „SplitActionBar”. (Nadal będzie działać na domyślnym pasku akcji Androida)

Oto jak: w pliku AndroidManifest.xml musisz dodać ten kod pod działaniem, w którym potrzebujesz przepełnionego menu.

android:uiOptions="splitActionBarWhenNarrow"

UWAGA: Twój przedmiot, który wypełnia twoje przepełnione menu, MUSIshowAsAction="always"

Vwola! masz przepełnione menu! Mam nadzieję, że ci pomogłem. :)

LeviRockerSk8er
źródło
3
Fajne rozwiązanie, lepsze niż hackowanie przycisku menu.
ol0
26

Na urządzeniach ze sprzętowymi przyciskami menu (Galaxy S3, uparty jak Samsung ...) przepełnione menu zachowuje się jak `` tradycyjne '' menu, używając przycisku menu sprzętowego.

Lukas Batteau
źródło
2
Stara odpowiedź, jednak z biblioteką kompatybilności po prostu natknęła się na bardzo dziwne wyniki: 3 urządzenia z przyciskiem sprzętowym, Uwaga 3 Neo = wyświetlane jest menu przepełnienia, przycisk menu nie działa, Uwaga 1 = brak przepełnienia, przycisk menu działa, Galaxy S3, nie przepełnienie, przycisk menu nie działa! To jest szalone.
3c71
5

Kiedy mówisz „przepełnione” menu, czy masz na myśli trzy kropki, które pojawiają się na końcu, aby wskazać, że jest więcej elementów ... czy masz na myśli podzielony pasek akcji, który pojawia się na dole dla przepełnionych elementów?

Jeśli masz na myśli podzielony pasek działań, dodaj go do pliku manifestu swojej aktywności

android:uiOptions="splitActionBarWhenNarrow"

Domyślnie menu przepełnienia trzema kropkami powinno pojawiać się automatycznie, więc trudno jest stwierdzić, na czym polega problem na podstawie informacji podanych powyżej.

wnafee
źródło
Mam na myśli trzy kropki. To nie jest tak, że
dzieje się
czy powinienem podać dodatkowe informacje, aby móc określić rzeczywisty problem?
Mats Raemen
Jaka jest twoja minSdkVersion, targetSdkVersion i wersja, na której testujesz?
Sparky
5
Czy Twoje urządzenie ma fizyczne przyciski menu, czy są to przyciski wirtualne, takie jak telefon galaxy nexus? Myślę, że trzy kropki pojawią się tylko wtedy, gdy Twój telefon nie ma fizycznych przycisków.
wnafee
5

Zawsze pokazuj przepełnienie akcji (trzy kropki) na actionbarcompat:
w pliku menu, przykład:
main.xml

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

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_about"
        android:title="@string/action_about"
        app:showAsAction="never"/>

</menu>

aw aktach:

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

U mnie działa dobrze.
Przetestowano na Google Nexus S, Samsung S3.

MrSiro
źródło
3

Wygląda na to, że na urządzeniach z przyciskiem menu rozszerzone menu nie jest wyświetlane na pasku akcji. Nie mamy również możliwości sprawdzenia, czy urządzenie ma przycisk menu sprzętowego przed poziomem API 14 (4.0+).

To rozwiązanie dodaje przycisk przepełnienia do a, android.support.v7.app.ActionBarktóry otwiera standardowe menu opcji tylko w wersji sprzed plastra miodu (<3.0), w przeciwnym razie pozostawia to dla systemu. W każdym razie możesz wybrać pomiędzy alwayslub ifRoomdla wszystkich działań.

Pobierz ikonę przepełnienia z pakietu ikon paska akcji .

Dodaj menu (mam kilka nieistotnych części, takich jak tytuły, zamówienie itp.)

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

<item
    android:id="@+id/action_overflow"
    android:orderInCategory="100"
    android:icon="@drawable/ic_action_overflow"
    app:showAsAction="always" />

<item
    android:id="@+id/action_first"
    app:showAsAction="always" />

<item
    android:id="@+id/action_second"
    app:showAsAction="ifRoom" />

</menu>

Usuń naszą akcję przepełnienia w wersji 3.0+

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        menu.removeItem(R.id.action_overflow);
    }
    return super.onPrepareOptionsMenu(menu);
}

Na koniec zadzwoń Activity.openOptionsMenu()z akcji przepełnienia.

Eee nie. Nie możesz nie zadzwonić openOptionsMenu()z przycisku menu ... ale jeśli używasz adnotacji Androida, możesz zrobić to łatwo:

@OptionsItem
void action_overflow() {
    openOptionsMenuDeferred();
}

@UiThread
void openOptionsMenuDeferred() {
    openOptionsMenu();
}

Jeśli nie, przypuszczam, że powinieneś zrobić coś takiego

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == id.action_overflow) {
        openOptionsMenuDeferred();
        return true;
    }
}

private Handler handler = new Handler(Looper.getMainLooper());
public void openOptionsMenuDeferred() {
    handler.post(new Runnable() {
        @Override
        public void run() {
            openOptionsMenu();
        }
    }
    );
}
IlDan
źródło
2

Spróbuj zmienić motyw aplikacji z Theme.AppCompat.Light.DarkActionBar na Theme.AppCompat.Light

Sagar Devanga
źródło
2

Umieść xmlns:your_app_name="http://schemas.android.com/apk/res-auto"tag menu wewnątrz i zamiast tego android:showAsAction="always"użyjyour_app_name:showAsAction="always"

np

<item
    android:id="@+id/action_search"
    android:icon="@drawable/icon_search"
    android:title="@string/search"
    your_app_name:showAsAction="ifRoom"/>

Rashmi Jain
źródło