I menu sono un componente comune dell'interfaccia utente in molti tipi di app. Per offrire un'esperienza utente familiare e coerente, utilizza le API Menu
per presentare le azioni utente e altre opzioni nelle tue attività.
Questo documento mostra come creare i tre tipi fondamentali di menu o presentazioni di azioni su tutte le versioni di Android:
- Menu Opzioni e barra delle app
- Il menu Opzioni è la raccolta principale di voci di menu per un'attività. È qui che inserisci le azioni che hanno un impatto globale sull'app, ad esempio "Ricerca", "Scrivi email" e "Impostazioni".
Consulta la sezione Creare un menu opzioni.
- Menu contestuale e modalità di azione contestuale
- Un menu contestuale è un menu mobile
che viene visualizzato quando l'utente tocca e tiene premuto un elemento. Fornisce azioni che influiscono sui contenuti o sul frame contestuale selezionati.
La modalità di azione contestuale mostra gli elementi di azione che interessano i contenuti selezionati in una barra nella parte superiore dello schermo e consente all'utente di selezionare più elementi.
Consulta la sezione Creare un menu contestuale.
- Menu popup
- Un menu popup mostra un elenco verticale di elementi ancorati alla visualizzazione che richiama il menu. È utile per fornire un overflow di azioni
correlate a contenuti specifici o per fornire opzioni per la seconda parte
di un comando. Le azioni in un menu popup non influiscono direttamente sui contenuti corrispondenti, per questo esistono le azioni contestuali. Il menu popup è invece destinato ad azioni avanzate relative alle regioni di contenuti nella tua attività.
Consulta la sezione Creare un menu popup.
Definire un menu in XML
Per tutti i tipi di menu, Android fornisce un formato XML standard per definire gli elementi del menu. Invece di creare un menu nel codice dell'attività, definisci un menu e tutti i relativi elementi in una risorsa menu XML. Puoi quindi gonfiare la risorsa del menu caricandola come oggetto Menu
nella tua attività o nel tuo frammento.
L'utilizzo di una risorsa menu è una buona prassi per i seguenti motivi:
- È più facile visualizzare la struttura del menu in XML.
- Separa i contenuti del menu dal codice di comportamento dell'app.
- Ti consente di creare configurazioni di menu alternative per versioni della piattaforma, dimensioni dello schermo e altre configurazioni diverse sfruttando il framework delle risorse app.
Per definire un menu, crea un file XML nella directory res/menu/
del progetto e crea il menu con i seguenti elementi:
<menu>
- Definisce un
Menu
, che è un contenitore per le voci di menu. Un elemento<menu>
deve essere il nodo principale del file e può contenere uno o più elementi<item>
e<group>
. <item>
- Crea un
MenuItem
, che rappresenta un singolo elemento in un menu. Questo elemento può contenere un elemento<menu>
nidificato per creare un sottomenu. <group>
- Un contenitore facoltativo e invisibile per gli elementi
<item>
. Ti consente di classificare gli elementi del menu in modo che condividano proprietà come stato attivo e visibilità. Per ulteriori informazioni, consulta la sezione Creare un gruppo di menu.
Ecco un menu di esempio denominato 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>
L'elemento <item>
supporta diversi attributi che puoi utilizzare per definire l'aspetto e il comportamento di un elemento. Gli elementi del menu precedente
includono i seguenti attributi:
android:id
- Un ID risorsa univoco per l'elemento, che consente all'app di riconoscerlo quando viene selezionato dall'utente.
android:icon
- Un riferimento a un drawable da utilizzare come icona dell'elemento.
android:title
- Un riferimento a una stringa da utilizzare come titolo dell'elemento.
android:showAsAction
- La specifica di quando e come questo elemento viene visualizzato come elemento di azione nella barra delle app.
Questi sono gli attributi più importanti che utilizzi, ma sono disponibili molti altri. Per informazioni su tutti gli attributi supportati, consulta la documentazione della risorsa Menu.
Puoi aggiungere un sottomenu a un elemento in qualsiasi menu aggiungendo un elemento <menu>
come elemento secondario di un <item>
.
I sottomenu sono utili quando l'app ha molte funzioni che possono essere organizzate in argomenti, ad esempio gli elementi nella barra dei menu di un'app per PC, come File, Modifica e Visualizza. Vedi il seguente esempio:
<?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>
Per utilizzare il menu nella tua attività, _gonfia_ la risorsa menu, convertendo la risorsa XML in un oggetto programmabile utilizzando MenuInflater.inflate()
.
Le sezioni seguenti mostrano come espandere un menu per ogni tipo di menu.
Creare un menu di opzioni
Nel menu delle opzioni, come quello mostrato nella figura 1, puoi includere azioni e altre opzioni pertinenti al contesto dell'attività corrente, ad esempio "Cerca", "Scrivi email" e "Impostazioni".
![Un'immagine che mostra la barra delle app per l'app Fogli Google](https://developer.android.google.cn/static/images/training/appbar/appbar_sheets_2x.png?authuser=3&hl=it)
Puoi dichiarare gli elementi per il menu opzioni dalla tua
Activity
sottoclasse o da una
Fragment
sottoclasse. Se sia l'attività sia i frammenti dichiarano elementi per il menu opzioni, gli elementi vengono combinati nell'interfaccia utente. Gli elementi dell'attività vengono visualizzati prima, seguiti da quelli di ciascun frammento, nell'ordine in cui i frammenti vengono aggiunti all'attività. Se necessario, puoi riordinare gli elementi del menu con
l'attributo android:orderInCategory
in ogni
<item>
da spostare.
Per specificare il menu opzioni per un'attività, sostituisci
onCreateOptionsMenu()
.
I frammenti forniscono il proprio callbackonCreateOptionsMenu()
. In questo metodo, puoi gonfiare la risorsa menu,
definita in XML, in Menu
fornito nel
callback. Ciò è mostrato nell'esempio seguente:
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; }
Puoi anche aggiungere voci di menu utilizzando
add()
e recuperare gli elementi con
findItem()
per rivederne le proprietà con le API MenuItem
.
Gestire gli eventi di clic
Quando l'utente seleziona un elemento dal menu delle opzioni, inclusi gli elementi di azione nella barra delle app, il sistema chiama il metodo onOptionsItemSelected()
della tua attività. Questo metodo passa il MenuItem
selezionato. Puoi identificare
l'elemento chiamando
getItemId()
,
che restituisce l'ID univoco dell'elemento del menu, definito dall'attributo
android:id
nella risorsa menu o con un numero intero fornito
al metodo add()
. Puoi associare questo ID a voci di menu
note per eseguire l'azione appropriata.
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); } }
Quando gestisci correttamente un elemento del menu, restituisci true
. Se
non gestisci la voce di menu, chiama l'implementazione della superclasse di
onOptionsItemSelected()
. L'implementazione predefinita restituisce
false.
Se l'attività include frammenti, il sistema chiama prima
onOptionsItemSelected()
per l'attività, poi per ogni frammento
nell'ordine in cui vengono aggiunti, finché uno non restituisce true
o
non vengono chiamati tutti i frammenti.
Modificare le voci di menu in fase di esecuzione
Dopo che il sistema chiama onCreateOptionsMenu()
, conserva un'istanza del Menu
che compili e non chiama di nuovo onCreateOptionsMenu()
, a meno che il menu non venga invalidato.
Tuttavia, utilizza onCreateOptionsMenu()
solo per creare lo stato iniziale del menu e non per apportare modifiche durante il ciclo di vita dell'attività.
Se vuoi modificare il menu delle opzioni in base agli eventi che si verificano durante il ciclo di vita dell'attività, puoi farlo nel metodo onPrepareOptionsMenu()
. Questo metodo ti passa l'oggetto Menu
così com'è attualmente, in modo da poterlo modificare, ad esempio aggiungendo, rimuovendo o disattivando elementi.
I frammenti forniscono anche un callbackonPrepareOptionsMenu()
.
Il menu opzioni è considerato sempre aperto quando gli elementi del menu vengono visualizzati nella barra delle app. Quando si verifica un evento e vuoi eseguire un aggiornamento del menu, chiama
invalidateOptionsMenu()
per richiedere che il sistema chiami onPrepareOptionsMenu()
.
Creare un menu contestuale
![Un'immagine che mostra un menu contestuale mobile](https://developer.android.google.cn/static/develop/ui/views/images/context_menu_no_icons.png?authuser=3&hl=it)
Un menu contestuale offre azioni che influiscono su un elemento o un frame contestuale specifico nell'interfaccia utente. Puoi fornire un menu contestuale per qualsiasi visualizzazione, ma vengono utilizzati più spesso per gli elementi di una raccolta di visualizzazioni RecylerView
o di altre in cui l'utente può eseguire azioni dirette su ogni elemento.
Esistono due modi per fornire azioni contestuali:
- In un menu contestuale mobile. Un menu viene visualizzato come elenco mobile di voci di menu, in modo simile a una finestra di dialogo, quando l'utente tocca e tiene premuta una visualizzazione che dichiara il supporto di un menu contestuale. Gli utenti possono eseguire un'azione contestuale su un solo elemento alla volta.
- Nella modalità di azione contestuale. Questa modalità è un'implementazione di sistema di
ActionMode
che mostra una barra di azioni contestuali(CAB) nella parte superiore dello schermo con elementi di azione che interessano gli elementi selezionati. Quando questa modalità è attiva, gli utenti possono eseguire un'azione su più elementi contemporaneamente, se la tua app lo supporta.
Nota: il menu contestuale non supporta le scorciatoie e le icone degli elementi.
Creare un menu contestuale mobile
Per fornire un menu contestuale mobile:
- Registra il
View
a cui è associato il menu contestuale chiamandoregisterForContextMenu()
e passandogli ilView
.Se la tua attività utilizza un
RecyclerView
e vuoi che ogni elemento fornisca lo stesso menu contestuale, registra tutti gli elementi per un menu contestuale passando ilRecyclerView
aregisterForContextMenu()
. - Implementa il metodo
onCreateContextMenu()
inActivity
oFragment
.Quando la visualizzazione registrata riceve un evento tocco e tieni premuto, il sistema chiama il tuo metodo
onCreateContextMenu()
. Qui definisci le voci del menu, in genere gonfiando una risorsa menu, come nell'esempio seguente: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); }
MenuInflater
consente di espandere il menu contestuale da una risorsa menu. I parametri del metodo callback includono ilView
selezionato dall'utente e un oggettoContextMenu.ContextMenuInfo
che fornisce informazioni aggiuntive sull'elemento selezionato. Se la tua attività ha diverse visualizzazioni che forniscono ciascuna un menu contestuale diverso, puoi utilizzare questi parametri per determinare quale menu contestuale espandere. Implementa
onContextItemSelected()
, come mostrato nell'esempio seguente. Quando l'utente seleziona un elemento del menu, il sistema chiama questo metodo in modo che tu possa eseguire l'azione appropriata.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); } }
Il metodo
getItemId()
interroga l'ID della voce di menu selezionata, che assegni a ogni voce di menu in XML utilizzando l'attributoandroid:id
, come mostrato in Definire un menu in XML.Quando gestisci correttamente un elemento del menu, restituisci
true
. Se non gestisci la voce di menu, passala all'implementazione della superclasse. Se l'attività include frammenti, riceve prima questo callback. Se non viene gestito, il sistema chiama la superclasse e poi passa l'evento al rispettivo metodo di callback in ogni frammento, uno alla volta, nell'ordine in cui viene aggiunto ogni frammento, fino a quando non viene restituitotrue
ofalse
. Le implementazioni predefinite perActivity
eandroid.app.Fragment
restituisconofalse
, quindi chiama sempre la superclasse quando non viene gestita.
Utilizzare la modalità di azione contestuale
La modalità di azioni contestuali è un'implementazione di sistema di
ActionMode
che concentra l'interazione dell'utente sull'esecuzione di
azioni contestuali. Quando un utente attiva questa modalità selezionando un elemento, nella parte superiore dello schermo viene visualizzata una barra di azioni contestuali che mostra le azioni che l'utente può eseguire sugli elementi selezionati. Quando questa modalità è attiva,
l'utente può selezionare più elementi, se la tua app lo supporta, e può deselezionare
gli elementi e continuare a navigare all'interno dell'attività. La modalità di azione viene disattivata
e la barra di azioni contestuali scompare quando l'utente deseleziona tutti gli elementi,
tocca il pulsante Indietro o l'azione Fine sul lato sinistro della
barra.
Per le visualizzazioni che forniscono azioni contestuali, in genere attivi la modalità di azione contestuale quando si verifica uno o entrambi i seguenti eventi:
- L'utente tocca e tiene premuta la visualizzazione.
- L'utente seleziona una casella di controllo o un componente dell'interfaccia utente simile all'interno della visualizzazione.
Il modo in cui l'app richiama la modalità di azioni contestuali e definisce il comportamento di ogni azione dipende dal design. Esistono due design:
- Per azioni contestuali su visualizzazioni arbitrarie e individuali.
- Per azioni contestuali collettive su gruppi di elementi in un
RecyclerView
, consentendo all'utente di selezionare più elementi e di eseguire un'azione su tutti.
Le seguenti sezioni descrivono la configurazione richiesta per il primo scenario.
Attivare la modalità di azione contestuale per le singole visualizzazioni
Se vuoi richiamare la modalità di azione contestuale solo quando l'utente seleziona visualizzazioni specifiche:
- Implementa l'interfaccia
ActionMode.Callback
come mostrato nell'esempio seguente. Nei metodi di callback, puoi specificare le azioni per la barra di azioni contestuale, rispondere agli eventi di clic sugli elementi di azione e gestire altri eventi di ciclo di vita per la modalità di azione.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; } };
Questi callback evento sono quasi esattamente uguali ai callback per il menu delle opzioni, tranne per il fatto che ognuno di questi passa anche l'oggetto
ActionMode
associato all'evento. Puoi utilizzare le APIActionMode
per apportare varie modifiche al CAB, ad esempio rivedere il titolo e il sottotitolo consetTitle()
esetSubtitle()
, utile per indicare il numero di elementi selezionati.L'esempio precedente imposta la variabile
actionMode
sunull
quando la modalità di azione viene distrutta. Nel passaggio successivo, scopri come viene inizializzata e come può essere utile salvare la variabile membro nell'attività o nel frammento. - Chiama
startActionMode()
quando vuoi mostrare la barra, ad esempio quando l'utente tocca e tiene premuta la visualizzazione.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; } });
Quando chiami
startActionMode()
, il sistema restituisce ilActionMode
creato. Salvandolo in una variabile membro, puoi apportare modifiche alla barra di azioni contestuali in risposta ad altri eventi. Nell'esempio precedente,ActionMode
viene utilizzato per assicurarsi che l'istanzaActionMode
non venga ricreata se è già attiva, controllando se il membro è nullo prima di avviare la modalità di azione.
Creare un menu popup
![Un'immagine che mostra un menu popup nell'app Gmail, ancorato al pulsante del menu extra in alto a destra.](https://developer.android.google.cn/static/images/ui/popupmenu.png?authuser=3&hl=it)
Un PopupMenu
è un menu modale ancorato a un View
. Viene visualizzato sotto la visualizzazione di ancoraggio se c'è spazio oppure sopra la visualizzazione. È utile per:
- Fornire un menu di tipo overflow per le azioni correlate a contenuti specifici, come le intestazioni delle email di Gmail, mostrato in figura 4.
- Fornire una seconda parte di una frase di comando, ad esempio un pulsante contrassegnato come Aggiungi che genera un menu popup con diverse opzioni di Aggiungi.
- Fornire un menu simile a un
Spinner
che non conserva una selezione permanente.
Se definisci il menu in XML, ecco come puoi mostrare il menu popup:
- Crea un'istanza di
PopupMenu
con il relativo costruttore, che prende l'app correnteContext
e ilView
a cui è ancorato il menu. - Utilizza
MenuInflater
per espandere la risorsa menu nell'oggettoMenu
restituito daPopupMenu.getMenu()
. - Chiama il numero
PopupMenu.show()
.
Ad esempio, ecco un pulsante che mostra un menu popup:
<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" />
L'attività può quindi mostrare il menu popup come segue:
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(); });
Il menu viene chiuso quando l'utente seleziona un elemento o tocca all'esterno dell'area del menu. Puoi ascoltare l'evento di dismiss utilizzando
PopupMenu.OnDismissListener
.
Gestire gli eventi di clic
Per eseguire un'azione quando l'utente seleziona un elemento del menu, implementa l'interfaccia PopupMenu.OnMenuItemClickListener
e registrala nel tuo PopupMenu
chiamando setOnMenuItemclickListener()
.
Quando l'utente seleziona un elemento, il sistema chiama il callback
onMenuItemClick()
nella tua interfaccia.
Ciò è mostrato nell'esempio seguente:
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; } }
Creare un gruppo di menu
Un gruppo di menu è una raccolta di voci di menu che condividono determinati tratti. Con un gruppo puoi:
- Mostra o nascondi tutti gli elementi utilizzando
setGroupVisible()
. - Attiva o disattiva tutti gli elementi utilizzando
setGroupEnabled()
. - Specifica se tutti gli elementi sono selezionabili utilizzando
setGroupCheckable()
.
Puoi creare un gruppo nidificando elementi <item>
all'interno di un elemento <group>
nella risorsa menu o specificando un ID gruppo con il metodo add()
.
Ecco un esempio di risorsa menu che include un gruppo:
<?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>
Gli elementi del gruppo vengono visualizzati allo stesso livello del primo elemento. Tutti e tre gli elementi del menu sono elementi fratelli. Tuttavia, puoi modificare
le caratteristiche dei due elementi del gruppo facendo riferimento all'ID gruppo e utilizzando
i metodi precedenti. Inoltre, il sistema non separa mai gli elementi raggruppati. Ad esempio, se dichiari android:showAsAction="ifRoom"
per ogni elemento, entrambi vengono visualizzati nella barra delle azioni o nell'overflow delle azioni.
Utilizzare le voci di menu che possono essere selezionate
Un menu può essere utile come interfaccia per attivare e disattivare le opzioni, utilizzando una casella di controllo per le opzioni autonome o i pulsanti di opzione per gruppi di opzioni mutuamente esclusive. La Figura 5 mostra un sottomenu con elementi che possono essere selezionati con pulsanti di opzione.
Puoi definire il comportamento di controllo per i singoli elementi del menu utilizzando l'attributo android:checkable
nell'elemento <item>
o per un intero gruppo con l'attributo android:checkableBehavior
nell'elemento <group>
. Ad esempio, tutti gli elementi di questo gruppo di menu possono essere selezionati con un pulsante di opzione:
<?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>
L'attributo android:checkableBehavior
accetta uno dei seguenti valori:
single
- È possibile selezionare un solo elemento del gruppo, con conseguente indicazione dei pulsanti di opzione.
all
- Tutti gli elementi possono essere selezionati, generando caselle di controllo.
none
- Nessun elemento può essere selezionato.
Puoi applicare uno stato di controllo predefinito a un elemento utilizzando l'attributo android:checked
nell'elemento <item>
e modificarlo nel codice con il metodo setChecked()
.
Quando viene selezionato un elemento che può essere selezionato, il sistema chiama il rispettivo metodo di callback di selezione dell'elemento, ad esempio onOptionsItemSelected()
.
Qui puoi impostare lo stato della casella di controllo, perché una casella di controllo o un pulsante di radio
non cambia automaticamente il suo stato. Puoi eseguire una query sullo stato corrente
dell'elemento, come era prima che l'utente lo selezionasse, con
isChecked()
e poi impostare lo stato selezionato con setChecked()
. Questo è mostrato nell'esempio seguente:
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); } }
Se non imposti lo stato di controllo in questo modo, lo stato visibile della casella di controllo o del pulsante di opzione non cambia quando l'utente li seleziona. Quando lo impostate, l'attività conserva lo stato di attivazione dell'elemento in modo che, quando l'utente apre il menu in un secondo momento, lo stato di attivazione impostato sia visibile.
Aggiungere voci di menu in base a un'intenzione
A volte vuoi che un elemento del menu avvii un'attività utilizzando un Intent
, che si tratti di un'attività nella tua app o in un'altra app. Quando conosci l'intent che vuoi utilizzare e hai un elemento del menu specifico che avvia l'intent, puoi eseguire l'intent con startActivity()
durante il metodo di callback appropriato per la selezione dell'elemento, ad esempio il callback onOptionsItemSelected()
.
Tuttavia, se non hai la certezza che il dispositivo dell'utente contenga un'app che gestisce l'intent, l'aggiunta di un elemento di menu che lo richiama può comportare un elemento di menu non funzionante, perché l'intent potrebbe non risolvere in un'attività. Per risolvere il problema, Android ti consente di aggiungere dinamicamente elementi al menu quando individua attività sul dispositivo che gestiscono l'intent.
Per aggiungere voci di menu in base alle attività disponibili che accettano un'intenzione, svolgi i seguenti passaggi:
- Definisci un'intenzione con la categoria
CATEGORY_ALTERNATIVE
oCATEGORY_SELECTED_ALTERNATIVE
, oppure con entrambe, oltre a eventuali altri requisiti. - Chiama
Menu.addIntentOptions()
. Android cerca quindi le app che possono eseguire l'intent e le aggiunge al menu.
Se non sono installate app che soddisfano l'intent, non vengono aggiunti elementi del menu.
Ciò è mostrato nell'esempio seguente:
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; }
Per ogni attività trovata che fornisce un filtro per intent corrispondente all'intent definito, viene aggiunto un elemento del menu utilizzando il valore in android:label
del filtro per intent come titolo dell'elemento del menu e l'icona dell'app come icona dell'elemento del menu. Il metodo addIntentOptions()
restituisce il numero di voci di menu aggiunte.
Consentire l'aggiunta delle tue attività ad altri menu
Puoi offrire i servizi della tua attività ad altre app in modo che la tua app possa essere inclusa nel menu di altre, invertendo i ruoli descritti in precedenza.
Per essere incluso in altri menu dell'app, definisci un filtro per intent come di consueto, ma includi i valori CATEGORY_ALTERNATIVE
o CATEGORY_SELECTED_ALTERNATIVE
o entrambi per la categoria del filtro per intent. Ciò è mostrato nell'esempio seguente:
<intent-filter label="@string/resize_image"> ... <category android:name="android.intent.category.ALTERNATIVE" /> <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> ... </intent-filter>
Scopri di più su come scrivere filtri di intenti in Intent e filtri di intenti.