Menüs sind eine gängige Benutzeroberflächenkomponente in vielen Arten von Apps. Verwenden Sie die Menu
APIs, um Nutzeraktionen und andere Optionen in Ihren Aktivitäten zu präsentieren und so eine vertraute und einheitliche Nutzererfahrung zu bieten.
In diesem Dokument wird gezeigt, wie Sie die drei grundlegenden Arten von Menüs oder Aktionsdarstellungen in allen Android-Versionen erstellen:
- Optionsmenü und App-Leiste
- Das Optionsmenü enthält die wichtigsten Menüpunkte für eine Aktivität. Hier platzieren Sie Aktionen, die sich global auf die App auswirken, z. B. „Suchen“, „E-Mail schreiben“ und „Einstellungen“.
Weitere Informationen finden Sie im Abschnitt Optionsmenü erstellen.
- Kontextmenü und Kontext-Aktionsbanner
- Ein Kontextmenü ist ein schwebendes Menü, das angezeigt wird, wenn der Nutzer ein Element gedrückt hält. Es bietet Aktionen, die sich auf den ausgewählten Inhalt oder Kontextbereich auswirken.
Im Kontextaktionsmodus werden Aktionselemente, die sich auf die ausgewählten Inhalte auswirken, in einer Leiste oben auf dem Bildschirm angezeigt. Der Nutzer kann mehrere Elemente auswählen.
Weitere Informationen finden Sie im Abschnitt Kontextmenü erstellen.
- Pop-up-Menü
- Ein Pop-up-Menü enthält eine vertikale Liste von Elementen, die an der Ansicht verankert ist, über die das Menü aufgerufen wird. Sie eignet sich gut, um eine Reihe von Aktionen für bestimmte Inhalte bereitzustellen oder Optionen für den zweiten Teil eines Befehls anzugeben. Aktionen in einem Pop-up-Menü wirken sich nicht direkt auf die entsprechenden Inhalte aus. Dafür sind kontextbezogene Aktionen gedacht. Das Pop-up-Menü enthält erweiterte Aktionen, die sich auf Inhaltsbereiche in Ihren Aktivitäten beziehen.
Weitere Informationen finden Sie im Abschnitt Pop-up-Menü erstellen.
Menü in XML definieren
Für alle Menütypen bietet Android ein Standard-XML-Format zum Definieren von Menüpunkten. Anstatt ein Menü im Code Ihrer Aktivität zu erstellen, definieren Sie ein Menü und alle seine Elemente in einer XML-Menüressource. Sie können die Menüressource dann in Ihrer Aktivität oder Ihrem Fragment als Menu
-Objekt laden.
Die Verwendung einer Menüressource ist aus folgenden Gründen empfehlenswert:
- Die Menüstruktur lässt sich in XML leichter visualisieren.
- So werden die Inhalte des Menüs vom Verhaltenscode Ihrer App getrennt.
- Sie können alternative Menükonfigurationen für verschiedene Plattformversionen, Bildschirmgrößen und andere Konfigurationen erstellen, indem Sie das Framework App-Ressourcen verwenden.
Wenn Sie ein Menü definieren möchten, erstellen Sie eine XML-Datei im Verzeichnis res/menu/
Ihres Projekts und erstellen Sie das Menü mit den folgenden Elementen:
<menu>
- Definiert einen
Menu
, einen Container für Menüpunkte. Ein<menu>
-Element muss der Stammknoten der Datei sein und kann ein oder mehrere<item>
- und<group>
-Elemente enthalten. <item>
- Erstellt eine
MenuItem
, die ein einzelnes Element in einem Menü darstellt. Dieses Element kann ein verschachteltes<menu>
-Element enthalten, um ein Untermenü zu erstellen. <group>
- Optionaler, unsichtbarer Container für
<item>
-Elemente. Sie können Menüpunkte so kategorisieren, dass sie gemeinsame Eigenschaften wie den aktiven Status und die Sichtbarkeit haben. Weitere Informationen finden Sie im Abschnitt Menügruppe erstellen.
Hier ein Beispiel für ein Menü namens game_menu.xml
:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/new_game" android:icon="@drawable/ic_new_game" android:title="@string/new_game" app:showAsAction="ifRoom"/> <item android:id="@+id/help" android:icon="@drawable/ic_help" android:title="@string/help" /> </menu>
Das Element <item>
unterstützt mehrere Attribute, mit denen Sie das Aussehen und Verhalten eines Elements definieren können. Die Elemente im vorherigen Menü haben die folgenden Attribute:
android:id
- Eine eindeutige Ressourcen-ID für das Element, anhand derer die App das Element erkennt, wenn der Nutzer es auswählt.
android:icon
- Eine Referenz auf ein drawable, das als Symbol des Elements verwendet werden soll.
android:title
- Ein Verweis auf einen String, der als Titel des Artikels verwendet werden soll.
android:showAsAction
- Die Angabe, wann und wie dieses Element als Aktionselement in der App-Leiste angezeigt wird.
Dies sind die wichtigsten Attribute, die Sie verwenden. Es gibt jedoch noch viele weitere. Informationen zu allen unterstützten Attributen finden Sie in der Dokumentation zur Menüressource.
Sie können einem Element in einem beliebigen Menü ein Untermenü hinzufügen, indem Sie ein <menu>
-Element als untergeordnetes Element eines <item>
hinzufügen.
Untermenüs sind nützlich, wenn Ihre App viele Funktionen hat, die nach Themen organisiert werden können, z. B. Elemente in der Menüleiste einer PC-Anwendung wie Datei, Bearbeiten und Ansicht. Sehen Sie sich folgendes Beispiel an:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/file" android:title="@string/file" > <!-- "file" submenu --> <menu> <item android:id="@+id/create_new" android:title="@string/create_new" /> <item android:id="@+id/open" android:title="@string/open" /> </menu> </item> </menu>
Wenn Sie das Menü in Ihrer Aktivität verwenden möchten, müssen Sie die Menüressource _aufblähen_, indem Sie die XML-Ressource mit MenuInflater.inflate()
in ein programmierbares Objekt konvertieren.
In den folgenden Abschnitten wird beschrieben, wie Sie ein Menü für jeden Menütyp maximieren.
Optionsmenü erstellen
Im Optionsmenü, wie in Abbildung 1 dargestellt, fügen Sie Aktionen und andere Optionen hinzu, die für den aktuellen Aktivitätskontext relevant sind, z. B. „Suchen“, „E-Mail schreiben“ und „Einstellungen“.
Sie können Elemente für das Optionsmenü aus Ihrer Activity
-Unterklasse oder einer Fragment
-Unterklasse deklarieren. Wenn sowohl Ihre Aktivität als auch Ihre Fragmente Elemente für das Optionsmenü angeben, werden die Elemente in der Benutzeroberfläche kombiniert. Die Elemente der Aktivität werden zuerst angezeigt, gefolgt von den Elementen der einzelnen Fragmente in der Reihenfolge, in der sie der Aktivität hinzugefügt werden. Bei Bedarf können Sie die Menüpunkte mit dem Attribut android:orderInCategory
in jeder <item>
neu anordnen, die Sie verschieben möchten.
Wenn Sie das Optionsmenü für eine Aktivität angeben möchten, überschreiben Sie onCreateOptionsMenu()
.
Fragmente haben einen eigenen onCreateOptionsMenu()
-Callback. Bei dieser Methode kannst du deine in XML definierte Menüressource in die im Rückruf bereitgestellte Menu
einfügen. Das ist im folgenden Beispiel zu sehen:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.game_menu, menu) return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.game_menu, menu); return true; }
Sie können Menüpunkte auch mit add()
hinzufügen und Elemente mit findItem()
abrufen, um ihre Properties mit MenuItem
APIs zu überarbeiten.
Click-Events verarbeiten
Wenn der Nutzer ein Element aus dem Optionsmenü auswählt, einschließlich Aktionselementen in der App-Leiste, ruft das System die Methode onOptionsItemSelected()
Ihrer Aktivität auf. Diese Methode übergibt die ausgewählte MenuItem
. Sie können den Artikel identifizieren, indem Sie getItemId()
aufrufen. Dadurch wird die eindeutige ID für den Menüpunkt zurückgegeben, die durch das Attribut android:id
in der Menüressource oder durch eine Ganzzahl definiert wird, die der Methode add()
übergeben wird. Sie können diese ID mit bekannten Menüpunkten abgleichen, um die entsprechende Aktion auszuführen.
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { // Handle item selection. return when (item.itemId) { R.id.new_game -> { newGame() true } R.id.help -> { showHelp() true } else -> super.onOptionsItemSelected(item) } }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection. switch (item.getItemId()) { case R.id.new_game: newGame(); return true; case R.id.help: showHelp(); return true; default: return super.onOptionsItemSelected(item); } }
Wenn du einen Menüpunkt erfolgreich verarbeitet hast, gib true
zurück. Wenn Sie den Menüpunkt nicht verarbeiten, rufen Sie die Superklasseimplementierung von onOptionsItemSelected()
auf. Die Standardimplementierung gibt „false“ zurück.
Wenn Ihre Aktivität Fragmente enthält, ruft das System zuerst onOptionsItemSelected()
für die Aktivität und dann für jedes Fragment in der Reihenfolge auf, in der die Fragmente hinzugefügt wurden, bis eines true
zurückgibt oder alle Fragmente aufgerufen wurden.
Menüpunkte zur Laufzeit ändern
Nachdem das System onCreateOptionsMenu()
aufgerufen hat, behält es eine Instanz der von Ihnen ausgefüllten Menu
bei und ruft onCreateOptionsMenu()
nur dann noch einmal auf, wenn das Menü ungültig wird.
Verwenden Sie onCreateOptionsMenu()
jedoch nur, um den ursprünglichen Menüstatus zu erstellen, und nicht, um während des Aktivitätszyklus Änderungen vorzunehmen.
Wenn Sie das Optionsmenü basierend auf Ereignissen ändern möchten, die während des Aktivitätszyklus auftreten, können Sie dies in der Methode onPrepareOptionsMenu()
tun. Bei dieser Methode wird das Menu
-Objekt in seiner aktuellen Form übergeben, damit Sie es ändern können, z. B. indem Sie Elemente hinzufügen, entfernen oder deaktivieren.
Fragmente bieten auch einen onPrepareOptionsMenu()
-Callback.
Das Optionsmenü gilt als immer geöffnet, wenn Menüpunkte in der App-Leiste angezeigt werden. Wenn ein Ereignis eintritt und du ein Menü aktualisieren möchtest, rufe invalidateOptionsMenu()
auf, um zu beantragen, dass das System onPrepareOptionsMenu()
aufruft.
Kontextmenü erstellen
Ein Kontextmenü bietet Aktionen, die sich auf ein bestimmtes Element oder einen bestimmten Kontextrahmen in der Benutzeroberfläche auswirken. Sie können ein Kontextmenü für jede Ansicht bereitstellen. Am häufigsten werden sie jedoch für Elemente in einer RecylerView
oder anderen Ansichtssammlung verwendet, in der Nutzer direkte Aktionen auf jedes Element ausführen können.
Es gibt zwei Möglichkeiten, kontextbezogene Aktionen bereitzustellen:
- In einem schwebenden Kontextmenü Ein Menü wird als schwebende Liste von Menüpunkten angezeigt, ähnlich wie ein Dialogfeld, wenn der Nutzer eine Ansicht gedrückt hält, die die Unterstützung eines Kontextmenüs angibt. Nutzer können eine kontextbezogene Aktion jeweils nur auf ein Element ausführen.
- Im Kontext-Aktionsbanner Dieser Modus ist eine Systemimplementierung von
ActionMode
. Oben auf dem Bildschirm wird eine Kontextaktionsleiste(Contextual Action Bar, CAB) mit Aktionselementen angezeigt, die sich auf die ausgewählten Elemente auswirken. Wenn dieser Modus aktiv ist, können Nutzer eine Aktion auf mehrere Elemente gleichzeitig ausführen, sofern Ihre App dies unterstützt.
Hinweis:Das Kontextmenü unterstützt keine Tastenkürzel und Symbole für Elemente.
Ein schwebendes Kontextmenü erstellen
So fügen Sie ein schwebendes Kontextmenü hinzu:
- Registrieren Sie die
View
, die dem Kontextmenü zugeordnet ist, indem SieregisterForContextMenu()
aufrufen und dieView
übergeben.Wenn in Ihrer Aktivität eine
RecyclerView
verwendet wird und jedes Element dasselbe Kontextmenü enthalten soll, registrieren Sie alle Elemente für ein Kontextmenü, indem Sie dieRecyclerView
anregisterForContextMenu()
übergeben. - Implementieren Sie die Methode
onCreateContextMenu()
inActivity
oderFragment
.Wenn die registrierte Ansicht ein Ereignis vom Typ „Berühren und halten“ empfängt, ruft das System die Methode
onCreateContextMenu()
auf. Hier definieren Sie die Menüpunkte, in der Regel durch Aufblasen einer Menüressource, wie im folgenden Beispiel:Kotlin
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) { super.onCreateContextMenu(menu, v, menuInfo) val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.context_menu, menu) }
Java
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); }
Mit
MenuInflater
lassen sich Kontextmenüs aus einer Menüressource aufblähen. Die Parameter der Callback-Methode umfassen die vom Nutzer ausgewählteView
und einContextMenu.ContextMenuInfo
-Objekt mit zusätzlichen Informationen zum ausgewählten Element. Wenn Ihre Aktivität mehrere Ansichten hat, die jeweils ein anderes Kontextmenü enthalten, können Sie mithilfe dieser Parameter festlegen, welches Kontextmenü maximiert werden soll. Implementieren Sie
onContextItemSelected()
wie im folgenden Beispiel gezeigt. Wenn der Nutzer einen Menüpunkt auswählt, ruft das System diese Methode auf, damit Sie die entsprechende Aktion ausführen können.Kotlin
override fun onContextItemSelected(item: MenuItem): Boolean { val info = item.menuInfo as AdapterView.AdapterContextMenuInfo return when (item.itemId) { R.id.edit -> { editNote(info.id) true } R.id.delete -> { deleteNote(info.id) true } else -> super.onContextItemSelected(item) } }
Java
@Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case R.id.edit: editNote(info.id); return true; case R.id.delete: deleteNote(info.id); return true; default: return super.onContextItemSelected(item); } }
Die Methode
getItemId()
fragt die ID für den ausgewählten Menüpunkt ab, die Sie jedem Menüpunkt in XML mit demandroid:id
-Attribut zuweisen, wie im Abschnitt Menü in XML definieren beschrieben.Wenn du einen Menüpunkt erfolgreich verarbeitet hast, gib
true
zurück. Wenn Sie den Menüpunkt nicht verarbeiten, übergeben Sie ihn an die Implementierung der Superklasse. Wenn Ihre Aktivität Fragmente enthält, wird dieser Rückruf zuerst an die Aktivität gesendet. Wenn die Superklasse bei nicht gehandhabten Ereignissen aufgerufen wird, übergibt das System das Ereignis nacheinander in der Reihenfolge, in der die einzelnen Fragmente hinzugefügt wurden, an die jeweilige Rückrufmethode in jedem Fragment, bistrue
oderfalse
zurückgegeben wird. Die Standardimplementierungen fürActivity
undandroid.app.Fragment
gebenfalse
zurück. Rufen Sie daher bei nicht verarbeiteten Ereignissen immer die Superklasse auf.
Kontext-Aktionsbanner verwenden
Der Modus für kontextbezogene Aktionen ist eine Systemimplementierung von ActionMode
, bei der die Nutzerinteraktion auf die Ausführung kontextbezogener Aktionen ausgerichtet ist. Wenn ein Nutzer diesen Modus durch Auswählen eines Elements aktiviert, wird oben auf dem Bildschirm eine Kontextaktionsleiste angezeigt, in der Aktionen aufgeführt sind, die der Nutzer auf die ausgewählten Elemente ausführen kann. Wenn dieser Modus aktiviert ist, kann der Nutzer mehrere Elemente auswählen, sofern Ihre App dies unterstützt. Er kann die Auswahl von Elementen aufheben und sich weiter in der Aktivität bewegen. Der Aktionsmodus wird deaktiviert und die kontextbezogene Aktionsleiste verschwindet, wenn der Nutzer die Auswahl aller Elemente aufhebt, auf die Schaltfläche „Zurück“ tippt oder links in der Leiste auf Fertig tippt.
Bei Ansichten mit kontextabhängigen Aktionen wird der Modus für kontextabhängige Aktionen in der Regel aufgerufen, wenn eines oder beide dieser beiden Ereignisse auftreten:
- Der Nutzer hält die Ansicht gedrückt.
- Der Nutzer wählt in der Ansicht ein Kästchen oder eine ähnliche UI-Komponente aus.
Wie Ihre App den Modus für kontextbezogene Aktionen aufruft und das Verhalten für jede Aktion definiert, hängt von Ihrem Design ab. Es gibt zwei Designs:
- Für kontextbezogene Aktionen auf einzelnen, beliebigen Ansichten.
- Für Batch-Kontextaktionen auf Gruppen von Elementen in einer
RecyclerView
, mit denen Nutzer mehrere Elemente auswählen und eine Aktion auf alle ausführen können.
In den folgenden Abschnitten wird die für das erste Szenario erforderliche Einrichtung beschrieben.
Kontext-Aktionsbanner für einzelne Aufrufe aktivieren
Wenn der Kontext-Aktionsbanner nur dann angezeigt werden soll, wenn der Nutzer bestimmte Ansichten auswählt, gehen Sie so vor:
- Implementieren Sie die
ActionMode.Callback
-Benutzeroberfläche wie im folgenden Beispiel gezeigt. In den Rückrufmethoden können Sie die Aktionen für die kontextbezogene Aktionsleiste angeben, auf Klickereignisse auf Aktionselemente reagieren und andere Lebenszyklusereignisse für den Aktionsmodus verarbeiten.Kotlin
private val actionModeCallback = object : ActionMode.Callback { // Called when the action mode is created. startActionMode() is called. override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { // Inflate a menu resource providing context menu items. val inflater: MenuInflater = mode.menuInflater inflater.inflate(R.menu.context_menu, menu) return true } // Called each time the action mode is shown. Always called after // onCreateActionMode, and might be called multiple times if the mode // is invalidated. override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { return false // Return false if nothing is done } // Called when the user selects a contextual menu item. override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_share -> { shareCurrentItem() mode.finish() // Action picked, so close the CAB. true } else -> false } } // Called when the user exits the action mode. override fun onDestroyActionMode(mode: ActionMode) { actionMode = null } }
Java
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() { // Called when the action mode is created. startActionMode() is called. @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items. MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); return true; } // Called each time the action mode is shown. Always called after // onCreateActionMode, and might be called multiple times if the mode // is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done. } // Called when the user selects a contextual menu item. @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.menu_share: shareCurrentItem(); mode.finish(); // Action picked, so close the CAB. return true; default: return false; } } // Called when the user exits the action mode. @Override public void onDestroyActionMode(ActionMode mode) { actionMode = null; } };
Diese Ereignis-Callbacks sind fast genau dieselben wie die Callbacks für das Optionsmenü, mit der Ausnahme, dass bei jedem dieser Callbacks auch das mit dem Ereignis verknüpfte
ActionMode
-Objekt übergeben wird. MitActionMode
APIs kannst du verschiedene Änderungen am CAB vornehmen, z. B. den Titel und den Untertitel mitsetTitle()
undsetSubtitle()
überarbeiten. Letzteres ist nützlich, um anzugeben, wie viele Elemente ausgewählt sind.Im vorherigen Beispiel wird die Variable
actionMode
aufnull
gesetzt, wenn der Aktionsmodus zerstört wird. Im nächsten Schritt erfahren Sie, wie die Variable initialisiert wird und wie das Speichern der Mitgliedsvariablen in Ihrer Aktivität oder Ihrem Fragment nützlich sein kann. - Rufen Sie
startActionMode()
auf, wenn die Leiste angezeigt werden soll, z. B. wenn der Nutzer die Ansicht gedrückt hält.Kotlin
someView.setOnLongClickListener { view -> // Called when the user performs a touch & hold on someView. when (actionMode) { null -> { // Start the CAB using the ActionMode.Callback defined earlier. actionMode = activity?.startActionMode(actionModeCallback) view.isSelected = true true } else -> false } }
Java
someView.setOnLongClickListener(new View.OnLongClickListener() { // Called when the user performs a touch & hold on someView. public boolean onLongClick(View view) { if (actionMode != null) { return false; } // Start the CAB using the ActionMode.Callback defined earlier. actionMode = getActivity().startActionMode(actionModeCallback); view.setSelected(true); return true; } });
Wenn Sie
startActionMode()
aufrufen, gibt das System die erstellteActionMode
zurück. Wenn Sie diesen Wert in einer Mitgliedsvariablen speichern, können Sie die Kontextaktionsleiste als Reaktion auf andere Ereignisse ändern. Im vorherigen Beispiel wirdActionMode
verwendet, um sicherzustellen, dass dieActionMode
-Instanz nicht neu erstellt wird, wenn sie bereits aktiv ist. Dazu wird geprüft, ob das Mitglied null ist, bevor der Aktionsmodus gestartet wird.
Pop-up-Menü erstellen
Ein PopupMenu
ist ein modales Menü, das an einem View
verankert ist. Sie wird unter der Ankeransicht angezeigt, sofern genügend Platz vorhanden ist, andernfalls darüber. Sie eignet sich für Folgendes:
- Ein Überlaufmenü für Aktionen, die sich auf bestimmte Inhalte beziehen, z. B. die E-Mail-Header in Gmail, wie in Abbildung 4 dargestellt.
- Ein zweiter Teil eines Befehlssatzes, z. B. eine Schaltfläche mit der Bezeichnung Hinzufügen, die ein Pop-up-Menü mit verschiedenen Hinzufügen-Optionen öffnet.
- Ein Menü ähnlich einem
Spinner
, das keine dauerhafte Auswahl beibehält.
Wenn Sie Ihr Menü in XML definieren, können Sie das Pop-up-Menü so anzeigen:
- Erstellen Sie eine Instanz von
PopupMenu
mit dem Konstruktor, der die aktuelle AppContext
und dieView
annimmt, an die das Menü angedockt ist. - Mit
MenuInflater
kannst du deine Menüressource in dasMenu
-Objekt einfügen, das vonPopupMenu.getMenu()
zurückgegeben wird. PopupMenu.show()
anrufen.
Hier ist beispielsweise eine Schaltfläche zu sehen, die ein Pop-up-Menü öffnet:
<ImageButton android:id="@+id/dropdown_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/descr_overflow_button" android:src="@drawable/arrow_drop_down" />
Das Pop-up-Menü kann dann so aussehen:
Kotlin
findViewById<ImageButton>(R.id.dropdown_menu).setOnClickListener { val popup = PopupMenu(this, it) val inflater: MenuInflater = popup.menuInflater inflater.inflate(R.menu.actions, popup.menu) popup.show() }
Java
findViewById(R.id.dropdown_menu).setOnClickListener(v -> { PopupMenu popup = new PopupMenu(this, v); popup.getMenuInflater().inflate(R.menu.actions, popup.getMenu()); popup.show(); });
Das Menü wird geschlossen, wenn der Nutzer einen Artikel auswählt oder außerhalb des Menübereichs tippt. Mit PopupMenu.OnDismissListener
können Sie das Ereignis „Schließen“ erfassen.
Click-Events verarbeiten
Wenn eine Aktion ausgeführt werden soll, wenn der Nutzer einen Menüpunkt auswählt, implementiere die PopupMenu.OnMenuItemClickListener
-Oberfläche und registriere sie bei deiner PopupMenu
, indem du setOnMenuItemclickListener()
aufrufst.
Wenn der Nutzer einen Artikel auswählt, ruft das System den onMenuItemClick()
-Callback in Ihrer Benutzeroberfläche auf.
Das ist im folgenden Beispiel zu sehen:
Kotlin
fun showMenu(v: View) { PopupMenu(this, v).apply { // MainActivity implements OnMenuItemClickListener. setOnMenuItemClickListener(this@MainActivity) inflate(R.menu.actions) show() } } override fun onMenuItemClick(item: MenuItem): Boolean { return when (item.itemId) { R.id.archive -> { archive(item) true } R.id.delete -> { delete(item) true } else -> false } }
Java
public void showMenu(View v) { PopupMenu popup = new PopupMenu(this, v); // This activity implements OnMenuItemClickListener. popup.setOnMenuItemClickListener(this); popup.inflate(R.menu.actions); popup.show(); } @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.archive: archive(item); return true; case R.id.delete: delete(item); return true; default: return false; } }
Menügruppe erstellen
Eine Menügruppe besteht aus einer Reihe von Menüelementen mit bestimmten gemeinsamen Merkmalen. Mit einer Gruppe haben Sie folgende Möglichkeiten:
- Mit
setGroupVisible()
können Sie alle Elemente ein- oder ausblenden. - Aktivieren oder deaktivieren Sie alle Elemente mit
setGroupEnabled()
. - Geben Sie an, ob alle Elemente mit
setGroupCheckable()
angeklickt werden können.
Sie können eine Gruppe erstellen, indem Sie <item>
-Elemente in einem <group>
-Element in Ihrer Menüressource verschachteln oder eine Gruppen-ID mit der Methode add()
angeben.
Hier ein Beispiel für eine Menüressource mit einer Gruppe:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_save" android:icon="@drawable/menu_save" android:title="@string/menu_save" /> <!-- menu group --> <group android:id="@+id/group_delete"> <item android:id="@+id/menu_archive" android:title="@string/menu_archive" /> <item android:id="@+id/menu_delete" android:title="@string/menu_delete" /> </group> </menu>
Die Elemente in der Gruppe werden auf derselben Ebene wie das erste Element angezeigt. Alle drei Elemente im Menü sind Geschwisterelemente. Sie können die Merkmale der beiden Elemente in der Gruppe jedoch ändern, indem Sie auf die Gruppen-ID verweisen und die oben genannten Methoden verwenden. Außerdem werden gruppierte Elemente nie getrennt. Wenn Sie beispielsweise android:showAsAction="ifRoom"
für jedes Element deklarieren, werden beide in der Aktionsleiste oder im Aktionsoverflow angezeigt.
Ankreuzbare Menüpunkte verwenden
Ein Menü kann als Benutzeroberfläche zum Aktivieren und Deaktivieren von Optionen nützlich sein. Verwenden Sie ein Kästchen für eigenständige Optionen oder Optionsfelder für Gruppen von sich gegenseitig ausschließenden Optionen. Abbildung 5 zeigt ein Untermenü mit Elementen, die über Optionsfelder aktiviert werden können.
Sie können das Ankreuzen für einzelne Menüpunkte mit dem android:checkable
-Attribut im <item>
-Element oder für eine ganze Gruppe mit dem android:checkableBehavior
-Attribut im <group>
-Element definieren. In diesem Beispiel können alle Elemente dieser Menügruppe mit einem Optionsfeld angeklickt werden:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/red" android:title="@string/red" /> <item android:id="@+id/blue" android:title="@string/blue" /> </group> </menu>
Für das android:checkableBehavior
-Attribut sind folgende Werte zulässig:
single
- Es kann jeweils nur ein Element aus der Gruppe ausgewählt werden, was zu Optionsfeldern führt.
all
- Alle Elemente können ausgewählt werden, was zu Kästchen führt.
none
- Keine Elemente können angeklickt werden.
Sie können einem Element mit dem Attribut android:checked
im Element <item>
einen standardmäßigen angeklickten Status zuweisen und ihn im Code mit der Methode setChecked()
ändern.
Wenn ein anklickbares Element ausgewählt wird, ruft das System die entsprechende Rückrufmethode für das ausgewählte Element auf, z. B. onOptionsItemSelected()
.
Hier legen Sie den Status des Kästchens fest, da sich der Status eines Kästchens oder einer Optionsschaltfläche nicht automatisch ändert. Sie können den aktuellen Status des Artikels, wie er vor der Auswahl durch den Nutzer war, mit isChecked()
abfragen und dann den angeklickten Status mit setChecked()
festlegen. Das ist im folgenden Beispiel zu sehen:
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.vibrate, R.id.dont_vibrate -> { item.isChecked = !item.isChecked true } else -> super.onOptionsItemSelected(item) } }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.vibrate: case R.id.dont_vibrate: if (item.isChecked()) item.setChecked(false); else item.setChecked(true); return true; default: return super.onOptionsItemSelected(item); } }
Wenn Sie den angeklickten Status nicht so festlegen, ändert sich der sichtbare Status des Kästchens oder Optionsfelds nicht, wenn der Nutzer es auswählt. Wenn Sie den Status festlegen, wird durch die Aktivität der angeklickte Status des Artikels beibehalten. Wenn der Nutzer das Menü später öffnet, ist der von Ihnen festgelegte angeklickte Status sichtbar.
Menüpunkte basierend auf einem Intent hinzufügen
Manchmal soll ein Menüpunkt eine Aktivität mithilfe einer Intent
starten, unabhängig davon, ob es sich um eine Aktivität in Ihrer App oder in einer anderen App handelt. Wenn Sie den Intent kennen, den Sie verwenden möchten, und einen bestimmten Menüpunkt haben, mit dem der Intent gestartet wird, können Sie den Intent mit startActivity()
während der entsprechenden Rückrufmethode für die Artikelauswahl ausführen, z. B. den onOptionsItemSelected()
-Rückruf.
Wenn Sie sich jedoch nicht sicher sind, ob das Gerät des Nutzers eine App enthält, die den Intent verarbeitet, kann das Hinzufügen eines Menüpunkts, der ihn aufruft, dazu führen, dass der Menüpunkt nicht funktioniert, da der Intent möglicherweise nicht auf eine Aktivität verweist. Um dieses Problem zu lösen, können Sie Ihrem Menü auf Android-Geräten dynamisch Menüpunkte hinzufügen, wenn Android Aktivitäten auf dem Gerät erkennt, die Ihre Absicht verarbeiten.
So fügen Sie Menüpunkte basierend auf verfügbaren Aktivitäten hinzu, die eine Absicht akzeptieren:
- Definieren Sie eine Absicht mit der Kategorie
CATEGORY_ALTERNATIVE
,CATEGORY_SELECTED_ALTERNATIVE
oder beiden sowie allen anderen Anforderungen. - Rufen Sie
Menu.addIntentOptions()
an. Android sucht dann nach Apps, die die Absicht ausführen können, und fügt sie dem Menü hinzu.
Wenn keine Apps installiert sind, die dem Intent entsprechen, werden keine Menüpunkte hinzugefügt.
Das ist im folgenden Beispiel zu sehen:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Create an Intent that describes the requirements to fulfill, to be // included in the menu. The offering app must include a category value // of Intent.CATEGORY_ALTERNATIVE. val intent = Intent(null, dataUri).apply { addCategory(Intent.CATEGORY_ALTERNATIVE) } // Search and populate the menu with acceptable offering apps. menu.addIntentOptions( R.id.intent_group, // Menu group to which new items are added. 0, // Unique item ID (none). 0, // Order for the items (none). this.componentName, // The current activity name. null, // Specific items to place first (none). intent, // Intent created above that describes the requirements. 0, // Additional flags to control items (none). null) // Array of MenuItems that correlate to specific items (none). return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu){ super.onCreateOptionsMenu(menu); // Create an Intent that describes the requirements to fulfill, to be // included in the menu. The offering app must include a category value // of Intent.CATEGORY_ALTERNATIVE. Intent intent = new Intent(null, dataUri); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); // Search and populate the menu with acceptable offering apps. menu.addIntentOptions( R.id.intent_group, // Menu group to which new items are added. 0, // Unique item ID (none). 0, // Order for the items (none). this.getComponentName(), // The current activity name. null, // Specific items to place first (none). intent, // Intent created above that describes the requirements. 0, // Additional flags to control items (none). null); // Array of MenuItems that correlate to specific items (none). return true; }
Für jede Aktivität, die einen Intent-Filter enthält, der mit dem definierten Intent übereinstimmt, wird ein Menüpunkt hinzugefügt. Dabei wird der Wert in android:label
des Intent-Filters als Menüpunkttitel und das App-Symbol als Menüpunktsymbol verwendet. Die Methode addIntentOptions()
gibt die Anzahl der hinzugefügten Menüpunkte zurück.
Aktivitäten zu anderen Menüs hinzufügen lassen
Sie können die Dienste Ihrer Aktivität anderen Apps anbieten, damit Ihre App in das Menü anderer Apps aufgenommen wird. Dabei werden die oben beschriebenen Rollen umgekehrt.
Wenn Sie in anderen App-Menüs enthalten sein möchten, definieren Sie einen Intent-Filter wie gewohnt, geben Sie aber die Werte CATEGORY_ALTERNATIVE
oder CATEGORY_SELECTED_ALTERNATIVE
oder beide für die Kategorie des Intent-Filters an. Das ist im folgenden Beispiel zu sehen:
<intent-filter label="@string/resize_image"> ... <category android:name="android.intent.category.ALTERNATIVE" /> <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> ... </intent-filter>
Weitere Informationen zum Erstellen von Intent-Filtern finden Sie unter Intents und Intent-Filter.