So erzwingen Sie die Verwendung des Überlaufmenüs auf Geräten mit der Menü-Taste

Ich möchte, dass alle Menüelemente, die nicht in die ActionBar passen, in das Überlaufmenü (das Menü, das über die Aktionsleiste und nicht über die Menüschaltfläche erreicht wird) gelangen, selbst auf Geräten mit einer Menüschaltfläche . Dies scheint für Benutzer viel intuitiver zu sein, als sie in eine separate Menüliste zu casting, die es erfordert, dass der Benutzer von einer Berührung (Bildschirm) zu einer knopfbasierten Interaktion springt, einfach weil das Layout der ActionBar nicht auf die Leiste passen kann.

Auf dem Emulator kann ich den Wert “Hardware Back / Home Keys” auf “no” setzen und diesen Effekt bekommen. Ich habe nach einer Möglichkeit gesucht, dies in Code für ein tatsächliches Gerät zu tun, das eine Menüschaltfläche hat, aber nicht in Ordnung ist. Kann mir jemand helfen?

EDIT: Geändert, um für die Situation der physischen Menü-Taste zu antworten.

Dies wird durch das Design tatsächlich verhindert. Laut dem Kompatibilitätsabschnitt des Android Design Guide ,

“… der Aktionsüberlauf ist über den Hardware-Schlüssel des Menüs verfügbar. Das resultierende Aktions-Popup … wird am unteren Bildschirmrand angezeigt.”

Sie werden feststellen, dass Telefone mit einer physischen Menüschaltfläche in den Screenshots kein Überlaufmenü in der ActionBar haben. Dies vermeidet Mehrdeutigkeiten für den Benutzer, im Wesentlichen mit zwei Tasten verfügbar, um das exakt gleiche Menü zu öffnen.

Um das Problem der Konsistenz zwischen den Geräten zu lösen: Letztendlich ist es für die Benutzer wichtiger, dass sich Ihre App konsistent mit jeder anderen App auf demselben Gerät verhält, als dass sie sich auf allen Geräten konsistent mit sich selbst verhält.

Sie können diesen kleinen Hack auch hier verwenden:

try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if (menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } } catch (Exception ignored) { } 

Ein guter Platz, um es zu setzen, wäre die onCreate -Methode Ihrer Anwendungsklasse.

Dadurch wird die App gezwungen, das Überlaufmenü anzuzeigen. Die Menüschaltfläche funktioniert weiterhin, öffnet jedoch das Menü in der oberen rechten Ecke.

[Edit] Da es nun schon mehrfach auftaucht: Dieser Hack funktioniert nur für die native ActionBar, die in Android 3.0 eingeführt wurde, nicht ActionBarSherlock. Letzterer verwendet seine eigene interne Logik, um zu entscheiden, ob das Überlaufmenü angezeigt werden soll. Wenn Sie ABS verwenden, werden alle Plattformen <4.0 von ABS bearbeitet und unterliegen somit ihrer Logik. Der Hack funktioniert immer noch für alle Geräte mit Android 4.0 oder höher (Sie können Android 3.x gefahrlos ignorieren, da es dort keine echten Tablets mit einem Menü-Button gibt).

Es gibt ein spezielles ForceOverflow-Theme, welches das Menü in ABS erzwingen wird, aber aufgrund zukünftiger Komplikationen wird es in zukünftigen Versionen entfernt .

Ich benutze es, um es zu umgehen, indem ich mein Menü so definiere (auch mit dem in meinem Beispiel verwendeten ActionBarSherlock-Icon):

         

Ich gebe zu, dass dies ein manuelles “Überlauf-Management” in Ihrem XML-System erforderlich macht, aber ich fand diese Lösung nützlich.

Sie können das Gerät auch zwingen, die HW-Taste zu verwenden, um das Überlaufmenü in Ihrer Aktivität zu öffnen:

 private Menu mainMenu; @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO: init menu here... // then: mainMenu=menu; return true; } @Override public boolean onKeyUp(int keycode, KeyEvent e) { switch(keycode) { case KeyEvent.KEYCODE_MENU: if (mainMenu !=null) { mainMenu.performIdentifierAction(R.id.menu_overflow, 0); } } return super.onKeyUp(keycode, e); } 

🙂

Wenn Sie die android.support.v7.app.ActionBar aus der Support-Bibliothek ( android.support.v7.app.ActionBar ) verwenden, verwenden Sie Folgendes:

 < ?xml version="1.0" encoding="utf-8"?>         

Diese Art von Methode wird vom Android Developers Design System verhindert, aber ich habe einen Weg gefunden, es zu bestehen:

Fügen Sie das zu Ihrer XML-Menüdatei hinzu:

  

Erstellen Sie als Nächstes eine class namens “AppPickActionProvider”, und kopieren Sie den folgenden Code:

  package com.example; import android.content.Context; import android.util.Log; import android.view.ActionProvider; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import android.view.SubMenu; import android.view.View; public class AppPickActionProvider extends ActionProvider implements OnMenuItemClickListener { static final int LIST_LENGTH = 3; Context mContext; public AppPickActionProvider(Context context) { super(context); mContext = context; } @Override public View onCreateActionView() { Log.d(this.getClass().getSimpleName(), "onCreateActionView"); return null; } @Override public boolean onPerformDefaultAction() { Log.d(this.getClass().getSimpleName(), "onPerformDefaultAction"); return super.onPerformDefaultAction(); } @Override public boolean hasSubMenu() { Log.d(this.getClass().getSimpleName(), "hasSubMenu"); return true; } @Override public void onPrepareSubMenu(SubMenu subMenu) { Log.d(this.getClass().getSimpleName(), "onPrepareSubMenu"); subMenu.clear(); subMenu.add(0, 1, 1, "Item1") .setIcon(R.drawable.ic_action_home).setOnMenuItemClickListener(this); subMenu.add(0, 2, 1, "Item2") .setIcon(R.drawable.ic_action_downloads).setOnMenuItemClickListener(this); } @Override public boolean onMenuItemClick(MenuItem item) { switch(item.getItemId()) { case 1: // What will happen when the user presses the first menu item ( 'Item1' ) break; case 2: // What will happen when the user presses the second menu item ( 'Item2' ) break; } return true; } } 

Nun, ich denke, dass Alexander Lucas die (leider) richtige Antwort geliefert hat, so dass ich sie als “richtig” bezeichne. Die alternative Antwort, die ich hier anführe, ist einfach, neue Leser auf diesen Beitrag im Android-Entwickler-Blog als eine ziemlich vollständige Diskussion des Themas hinzuweisen, mit einigen spezifischen Vorschlägen, wie man mit dem Code beim Übergang von Level 11 vorgeht zur neuen Aktionsleiste.

Ich glaube immer noch, dass es ein Designerrors war, dass sich die Menütaste nicht wie eine redundante “Action Overflow” -Schaltfläche in Menüschaltflächen-aktivierten Geräten verhält, sondern das Wasser unter der Brücke an dieser Stelle besser umgeht.

Ich bin mir nicht sicher, ob Sie das suchen, aber ich habe ein Untermenü im Menü der ActionBar erstellt und sein Symbol so eingestellt, dass es dem Icon des Überlaufmenüs entspricht. Es werden zwar keine Einträge automatisch gesendet (IE muss wählen, was immer sichtbar ist und was immer übergelaufen ist), aber mir scheint, dass dieser Ansatz Ihnen helfen kann.

In der Gmail-App, die mit ICS vorinstalliert ist, ist die Menüschaltfläche deaktiviert, wenn Sie mehrere Elemente ausgewählt haben. Das Überlaufmenü wird hier durch die Verwendung der Überlauftaste anstelle der physikalischen Menü-Taste “gezwungen” ausgetriggers. Theres eine 3rd-Party-Lib namens ActionBarSherlock, mit dem Sie das Überlaufmenü “erzwingen” können. Dies funktioniert jedoch nur auf API-Stufe 14 oder niedriger (vor ICS).

Wenn Sie die Toolbar verwenden , können Sie den Überlauf auf allen Versionen und allen Geräten anzeigen, ich habe es auf einigen 2.x Geräten versucht, es funktioniert.

Entschuldigung, wenn dieses Problem tot ist.

Hier ist, was ich getan habe, um den Fehler zu beheben. Ich ging zu Layouts und erstellte zwei mit Symbolleisten. Einer war ein Layout für sdk Version 8 und der andere war für SDK Version 21. In Version 8 habe ich die android.support.v7.widget.Toolbar verwendet, während ich android.widget.Toolbar auf dem SDK 21 Layout verwendet habe.

Dann blende ich die Symbolleiste in meiner Aktivität auf. Ich überprüfe das SDK, um zu sehen, ob es 21 oder höher war. Ich blase dann das entsprechende Layout auf. Dies zwingt die Hardware-Schaltfläche, auf die Symbolleiste, die Sie tatsächlich entworfen haben, zuzuordnen.

Für jeden, der die neue Toolbar nutzt:

 private Toolbar mToolbar; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); ... } @Override public boolean onKeyUp(int keycode, KeyEvent e) { switch(keycode) { case KeyEvent.KEYCODE_MENU: mToolbar.showOverflowMenu(); return true; } return super.onKeyUp(keycode, e); }