I menu sono un componente dell'interfaccia utente comune in molti tipi di app. Per
fornire un'esperienza utente familiare e coerente, usa 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 di un'attività. Qui puoi inserire le azioni che hanno un impatto globale sull'app, ad esempio "Cerca", "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 tieni premuto un elemento. Fornisce azioni che influiscono sui contenuti o sul frame di contesto selezionati.
La modalità di azione contestuale mostra le attività 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 relative 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, ecco a cosa servono le azioni contestuali. Il menu popup, invece, mostra le azioni estese relative ad aree geografiche di contenuti nella tua attività.
Consulta la sezione Creare un menu popup.
Definisci un menu in XML
Per tutti i tipi di menu, Android mette a disposizione un formato XML standard per definire le voci di menu. Anziché creare un menu nel codice dell'attività, definisci un menu e tutte le sue voci in una risorsa di menu XML. Puoi quindi gonfiare la risorsa di menu, caricandola come oggetto Menu
, nell'attività o nel frammento.
L'utilizzo di una risorsa del menu è una buona pratica per i seguenti motivi:
- È più facile visualizzare la struttura del menu in XML.
- I contenuti del menu vengono separati dal codice comportamentale dell'app.
- Consente di creare configurazioni di menu alternative per versioni di piattaforme, dimensioni dello schermo e altre configurazioni diverse sfruttando il framework delle risorse dell'app.
Per definire un menu, crea un file XML all'interno della directory res/menu/
del progetto e genera il menu con i seguenti elementi:
<menu>
- Definisce un
Menu
, che è un contenitore per le voci del menu. Un elemento<menu>
deve essere il nodo radice del file e può contenere uno o più elementi<item>
e<group>
. <item>
- Crea un elemento
MenuItem
, che rappresenta una singola voce in un menu. Questo elemento può contenere un elemento<menu>
nidificato per creare un sottomenu. <group>
- Un contenitore invisibile e facoltativo per gli elementi
<item>
. Consente di classificare le voci di menu in modo che condividano proprietà come stato attivo e visibilità. Per maggiori informazioni, consulta la sezione Creare un gruppo di menu.
Ecco un menu di esempio chiamato 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. Le voci nel menu precedente includono i seguenti attributi:
android:id
- Un ID risorsa univoco per l'elemento, che consente all'app di riconoscere l'elemento quando viene selezionato dall'utente.
android:icon
- Un riferimento a una risorsa da utilizzare come icona dell'elemento.
android:title
- Un riferimento a una stringa da utilizzare come titolo dell'elemento.
android:showAsAction
- Le specifiche relative a quando e come questo elemento viene visualizzato come attività nella barra dell'app.
Questi sono gli attributi più importanti che utilizzi, ma ce ne sono molti altri. Per informazioni su tutti gli attributi supportati, consulta la documentazione delle risorse del menu.
Puoi aggiungere un sottomenu a un elemento di qualsiasi menu aggiungendo un elemento <menu>
come elemento secondario di <item>
.
I sottomenu sono utili quando l'app ha molte funzioni che possono essere organizzate in argomenti, ad esempio, elementi nella barra dei menu di un'app per PC, come File, Modifica e Visualizza. Vedi l'esempio che segue:
<?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à, _inflate_ la risorsa di menu, convertendo
la risorsa XML in un oggetto programmabile utilizzando
MenuInflater.inflate()
.
Le seguenti sezioni mostrano come gonfiare un menu per ogni tipo di menu.
Crea un menu opzioni
Il menu delle opzioni, come quello nella Figura 1, consente di includere azioni e altre opzioni pertinenti al contesto dell'attività corrente, ad esempio "Cerca", "Scrivi email" e "Impostazioni".
Puoi dichiarare gli elementi del menu Opzioni dalla tua
sottoclasse Activity
o da una
sottoclasse Fragment
. Se sia l'attività sia i frammenti dichiarano elementi del menu opzioni, questi vengono combinati nella UI. Gli elementi dell'attività vengono visualizzati per primi, seguiti da quelli di ogni frammento, nell'ordine in cui i frammenti vengono aggiunti all'attività. Se necessario, puoi riordinare le voci di menu con
l'attributo android:orderInCategory
in ogni
<item>
che vuoi spostare.
Per specificare il menu opzioni per un'attività, esegui l'override di onCreateOptionsMenu()
.
I frammenti forniscono un proprio
onCreateOptionsMenu()
callback. In questo metodo, puoi gonfiare la risorsa di menu, definita in XML, in Menu
fornita nel callback. come illustrato 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 rivedere le proprietà con le API MenuItem
.
Gestire gli eventi di clic
Quando l'utente seleziona una voce dal menu delle opzioni, incluse le attività nella barra dell'app, il sistema chiama il metodo onOptionsItemSelected()
dell'attività. Questo metodo trasmette il valore MenuItem
selezionato. Puoi identificare
l'elemento richiamando
getItemId()
,
che restituisce l'ID univoco della voce di menu, definito dall'attributo
android:id
nella risorsa di menu o con un numero intero assegnato
al metodo add()
. Puoi associare questo ID a voci di menu
note per compiere 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 una voce di 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 vengono aggiunti i frammenti, finché non viene restituito true
o
vengono chiamati tutti i frammenti.
Modificare le voci di menu in fase di runtime
Dopo che il sistema chiama onCreateOptionsMenu()
, conserva un'istanza
di Menu
che compili e non chiama più
onCreateOptionsMenu()
a meno che il menu non venga invalidato.
Tuttavia, usa 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 Opzioni in base agli eventi che si verificano durante il ciclo di vita dell'attività, puoi utilizzare il metodo onPrepareOptionsMenu()
. Questo metodo ti trasmette l'oggetto Menu
così come esiste
attualmente, per consentirti di modificarlo, ad esempio aggiungendo, rimuovendo o disattivando gli elementi.
I frammenti forniscono anche un
onPrepareOptionsMenu()
callback.
Il menu delle opzioni è considerato sempre aperto quando le voci di menu sono presentate
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 menu contestuale offre azioni che hanno effetto su un elemento
o un frame di contesto specifico nell'interfaccia utente. Puoi fornire un menu contestuale per qualsiasi vista, ma nella maggior parte dei casi questi vengono utilizzati per gli elementi di un elemento in RecylerView
o in altre raccolte di viste in cui l'utente può eseguire azioni dirette su ciascun elemento.
Esistono due modi per fornire azioni contestuali:
- In un menu contestuale mobile. Un menu viene visualizzato come un elenco mobile di voci di menu, come una finestra di dialogo, quando l'utente esegue il tocco e la pressione su una vista che dichiara il supporto di un menu contestuale. Gli utenti possono eseguire un'azione contestuale su un elemento alla volta.
- In modalità azione contestuale. Questa modalità è un'implementazione di sistema di
ActionMode
che mostra una barra delle azioni contestuale, o CAB, nella parte superiore dello schermo con attività che interessano gli elementi selezionati. Quando questa modalità è attiva, gli utenti possono eseguire un'azione su più elementi contemporaneamente, se la tua app la supporta.
Creare un menu contestuale mobile
Per fornire un menu contestuale mobile:
- Registra il
View
a cui è associato il menu contestuale chiamandoregisterForContextMenu()
e passando 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 passandoRecyclerView
aregisterForContextMenu()
. - Implementa il metodo
onCreateContextMenu()
inActivity
oFragment
.Quando la visualizzazione registrata riceve un evento tocco e pressione, il sistema chiama il tuo metodo
onCreateContextMenu()
. Qui puoi definire le voci di menu, in genere gonfiando una risorsa di 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 gonfiare il menu contestuale da una risorsa di menu. I parametri del metodo di callback includono ilView
selezionato dall'utente e un oggettoContextMenu.ContextMenuInfo
che fornisce informazioni aggiuntive sull'elemento selezionato. Se la tua attività ha più visualizzazioni che offrono ciascuna un menu contestuale diverso, puoi utilizzare questi parametri per determinare quale menu contestuale aumentare. Implementa
onContextItemSelected()
, come mostrato nell'esempio seguente. Quando l'utente seleziona una voce di menu, il sistema chiama questo metodo per consentirti di 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()
esegue una query sull'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 una voce di menu, restituisci
true
. Se non gestisci la voce di menu, passala all'implementazione della superclasse. Se l'attività include frammenti, l'attività riceve prima questo callback. Richiamando la superclasse quando non è gestita, il sistema passa l'evento al rispettivo metodo di callback in ciascun frammento, uno alla volta, nell'ordine di aggiunta di ciascun frammento, finché non vengono restituititrue
ofalse
. Le implementazioni predefinite perActivity
eandroid.app.Fragment
restituisconofalse
, quindi chiama sempre la superclasse se non gestita.
Utilizzare la modalità di azione contestuale
La modalità di azione contestuale è 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 delle azioni contestuale 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, deselezionarli e continuare a navigare all'interno dell'attività. La modalità di azione è disattivata e la barra delle azioni contestuale scompare quando l'utente deseleziona tutti gli elementi, tocca il pulsante Indietro oppure tocca l'azione Fine sul lato sinistro della barra.
Per le visualizzazioni che offrono azioni contestuali, di solito richiami la modalità di azione contestuale quando si verificano uno o entrambi i seguenti eventi:
- L'utente tocca e tieni premuto sulla vista.
- L'utente seleziona una casella di controllo o un componente dell'interfaccia utente simile all'interno della vista.
Il modo in cui l'app richiama la modalità di azione contestuale e definisce il comportamento di ogni azione dipende dal tuo design. Sono disponibili due design:
- Per azioni contestuali relative a singole visualizzazioni arbitrarie.
- Per azioni contestuali collettive sui gruppi di elementi in un
RecyclerView
, consentendo all'utente di selezionare più elementi ed eseguire un'azione su tutti.
Le seguenti sezioni descrivono la configurazione richiesta per ogni scenario.
Attivare la modalità di azione contestuale per le singole visualizzazioni
Se vuoi richiamare la modalità di azione contestuale solo quando l'utente seleziona viste specifiche, procedi nel seguente modo:
- Implementa l'interfaccia
ActionMode.Callback
come mostrato nell'esempio seguente. Nei relativi metodi di callback, puoi specificare le azioni per la barra delle azioni contestuale, rispondere agli eventi di clic sulle attività e gestire altri eventi del ciclo di vita per la modalità 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 degli eventi sono quasi identici ai callback del menu opzioni, ad eccezione del 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()
, che sono utili per indicare quanti elementi sono selezionati.Nell'esempio precedente, la variabile
actionMode
viene impostata sunull
quando viene eliminata la modalità di azione. 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 tieni premuta la vista.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 il tokenActionMode
creato. Se salvi questo elemento in una variabile membro, puoi apportare modifiche alla barra delle azioni contestuali in risposta ad altri eventi. Nell'esempio precedente,ActionMode
viene utilizzato per garantire che l'istanzaActionMode
non venga ricreata se è già attiva, verificando se il membro è null prima di avviare la modalità di azione.
Crea un menu popup
Un elemento PopupMenu
è un menu modale ancorato a un elemento View
. Viene visualizzato sotto la vista ancorata, se c'è spazio, o sopra la vista. È utile per quanto segue:
- Fornisce un menu di tipo extra per le azioni correlate a contenuti specifici, come le intestazioni delle email di Gmail, mostrate nella figura 4.
- Fornisce una seconda parte di una frase del comando, ad esempio un pulsante contrassegnato come Aggiungi che produce un menu popup con diverse opzioni Aggiungi.
- Fornisce un menu simile a un elemento
Spinner
che non conserva una selezione persistente.
Se definisci il menu in XML, ecco come puoi mostrare il menu popup:
- Crea un'istanza
PopupMenu
con il suo costruttore, che prende l'app correnteContext
eView
a cui è ancorato il menu. - Usa
MenuInflater
per gonfiare la risorsa di 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 in questo modo:
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 ignorato quando l'utente seleziona un elemento o tocca fuori dall'area del menu. Puoi ascoltare l'evento ignorato utilizzando PopupMenu.OnDismissListener
.
Gestire gli eventi di clic
Per eseguire un'azione quando l'utente seleziona una voce di menu, implementa l'interfaccia PopupMenu.OnMenuItemClickListener
e registrala con il tuo PopupMenu
chiamando setOnMenuItemclickListener()
.
Quando l'utente seleziona un elemento, il sistema chiama il callback onMenuItemClick()
nell'interfaccia.
come illustrato 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; } }
Crea un gruppo di menu
Un gruppo di menu è una raccolta di voci di menu che condividono determinati tratti. Con un gruppo puoi fare quanto segue:
- Mostra o nascondi tutti gli elementi utilizzando
setGroupVisible()
. - Attiva o disattiva tutti gli elementi che utilizzano
setGroupEnabled()
. - Specifica se tutti gli elementi possono essere controllati utilizzando
setGroupCheckable()
.
Puoi creare un gruppo nidificando gli elementi <item>
all'interno di un elemento <group>
nella risorsa di menu o specificando un ID gruppo con il metodo add()
.
Ecco un esempio di risorsa di 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 nel gruppo vengono visualizzati allo stesso livello della prima voce (tutte e tre le voci nel menu sono di pari livello). Tuttavia, puoi modificare i tratti 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, vengono visualizzati entrambi nella barra delle azioni o nell'overflow delle azioni.
Utilizzare voci di menu selezionabili
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 che si escludono a vicenda. La figura 5 mostra un sottomenu con voci selezionabili con i pulsanti di opzione.
Puoi definire il comportamento verificabile per le singole voci di menu utilizzando l'attributo android:checkable
nell'elemento <item>
o per un intero gruppo con l'attributo android:checkableBehavior
nell'elemento <group>
. Ad esempio, tutte le voci di questo gruppo di menu possono essere selezionate 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 controllare una sola voce del gruppo e visualizzare pulsanti di opzione.
all
- È possibile selezionare tutti gli elementi e includere delle caselle di controllo.
none
- Nessun elemento selezionabile.
Puoi applicare uno stato selezionato 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 selezionabile, il sistema chiama il rispettivo metodo di callback selezionato, ad esempio onOptionsItemSelected()
.
È qui che puoi impostare lo stato della casella di controllo, perché una casella di controllo o un pulsante di opzione non cambia automaticamente lo stato. Puoi eseguire una query sullo stato attuale dell'elemento, com'era prima che l'utente lo selezionasse, con isChecked()
, quindi impostare lo stato selezionato con setChecked()
. come 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 selezionato in questo modo, lo stato visibile della casella di controllo o del pulsante di opzione non cambia quando l'utente lo seleziona. Quando imposti lo stato, l'attività conserva lo stato selezionato dell'elemento in modo che, quando l'utente apre il menu in un secondo momento, lo stato selezionato impostato sia visibile.
Aggiungere voci di menu in base a un intent
A volte potresti volere che una voce di menu avvii un'attività utilizzando Intent
, che si tratti di un'attività nella tua app o in un'altra app. Quando conosci l'intent che vuoi utilizzare e hai una voce di menu specifica che avvia l'intent, puoi eseguire l'intent con startActivity()
durante il metodo di callback appropriato selezionato sull'elemento, come il callback onOptionsItemSelected()
.
Tuttavia, se non hai la certezza che il dispositivo dell'utente contenga un'app che gestisce l'intent, l'aggiunta di una voce di menu che la richiama può comportare una voce di menu non funzionante, perché l'intent potrebbe non risolversi in un'attività. Per risolvere questo problema, Android ti consente di aggiungere in modo dinamico voci di menu al menu quando Android trova sul dispositivo attività che gestiscono il tuo intento.
Per aggiungere voci di menu in base alle attività disponibili che accettano un intent:
- Definisci un intent con la categoria
CATEGORY_ALTERNATIVE
oCATEGORY_SELECTED_ALTERNATIVE
o entrambe, oltre a qualsiasi altro requisito. - Chiama il numero
Menu.addIntentOptions()
. Android cerca quindi tutte le app in grado di eseguire l'intent e le aggiunge al menu.
Se non ci sono app installate che soddisfano l'intent, non vengono aggiunte voci di menu.
come illustrato 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 aggiunta una voce di menu, utilizzando il valore nell'elemento android:label
del filtro per intent come titolo della voce di menu e l'icona dell'app come icona della voce di menu. Il metodo addIntentOptions()
restituisce il numero di voci di menu aggiunte.
Consenti di aggiungere la tua attività ad altri menu
Puoi offrire i servizi relativi alle tue attività ad altre app in modo che la tua app possa essere inclusa nel menu di altre app, 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 di filtro per intent. come illustrato 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ù sulla scrittura di filtri per intent in Intent e filtri di intent.