La barra delle app in alto fornisce un punto coerente lungo la parte superiore della finestra dell'app per la visualizzazione informazioni e azioni della schermata corrente.
La proprietà della barra delle app varia in base alle esigenze dell'app. Quando
utilizzando frammenti, la barra delle app può essere implementata come
ActionBar
di proprietà
dall'attività host o da una barra degli strumenti nel layout del frammento.
Se tutti gli schermi utilizzano la stessa barra delle app che si trova sempre in alto estende la larghezza dello schermo, usa un modello fornito dal tema, barra delle azioni ospitata dall'attività. L'utilizzo delle barre delle app a tema permette di mantenere dall'aspetto coerente e fornire uno spazio per ospitare menu di opzioni e Pulsante Su.
Utilizza una barra degli strumenti ospitata dal frammento se vuoi avere un maggiore controllo le dimensioni, il posizionamento e l'animazione della barra delle app su più schermate. Ad esempio, potresti aver bisogno di una barra delle app comprimibile o di una non occupa solo metà della larghezza dello schermo ed è centrato verticalmente.
Situazioni diverse richiedono approcci diversi, come il gonfiaggio i menu e rispondere all'interazione dell'utente. Comprendere le diverse e impiegare il migliore per la tua app ti fa risparmiare tempo e per assicurarti che l'app funzioni correttamente.
Gli esempi in questo argomento fanno riferimento a un ExampleFragment
che contiene
un profilo modificabile. Il frammento gonfia quanto segue
Menu definito da XML nella barra delle app:
<!-- sample_menu.xml -->
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_done"
android:icon="@drawable/ic_done"
android:title="@string/done"
app:showAsAction="ifRoom|withText"/>
</menu>
Il menu contiene due opzioni: una per accedere alla schermata di un profilo e una per salvare le modifiche apportate al profilo.
Barra delle app di proprietà delle attività
La barra delle app è di solito di proprietà dell'attività di organizzatore. Quando l'app barra è di proprietà di un'attività, i frammenti possono interagire con la barra delle app eseguendo l'override dei metodi del framework richiamati durante la creazione dei frammenti.
Registrati con l'attività
Devi comunicare al sistema che il frammento della barra dell'app è presente
nel popolamento del menu opzioni. A questo scopo, chiama
setHasOptionsMenu(true)
nel metodo onCreate(Bundle)
del frammento, come mostrato di seguito
esempio:
Kotlin
class ExampleFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) } }
Java
public class ExampleFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } }
setHasOptionsMenu(true)
indica al sistema che il frammento
vuole ricevere callback relativi al menu. Quando un evento legato al menu
si verifica un evento, come un clic, il metodo di gestione eventi è
chiamato per la prima volta sull'attività prima di essere chiamato sul frammento.
Tuttavia, non fare affidamento su questo ordine nella logica dell'applicazione. Se lo stesso l'attività ospita più frammenti, ogni frammento può fornire menu opzioni, nel qual caso l'ordine di callback dipende dall'ordine in a cui vengono aggiunti i frammenti.
Amplia il menu
Per unire il menu al menu opzioni della barra delle app, sostituisci
onCreateOptionsMenu()
nel tuo frammento. Questo metodo riceve il menu della barra delle app corrente e un
MenuInflater
come parametri. Utilizza le funzionalità di
strumento di riempimento del menu per creare un'istanza del menu del frammento,
uniscile al menu corrente, come illustrato nell'esempio seguente:
Kotlin
class ExampleFragment : Fragment() { ... override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { inflater.inflate(R.menu.sample_menu, menu) } }
Java
public class ExampleFragment extends Fragment { ... @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.sample_menu, menu); } }
La figura 2 mostra il menu aggiornato.
Gestire gli eventi di clic
Ogni attività e frammento che partecipa al menu opzioni possono
rispondi al tocco. Il frammento
onOptionsItemSelected()
riceve la voce di menu selezionata come parametro e restituisce un valore booleano
per indicare se il tocco viene consumato. Una volta
l'attività o il frammento restituisce true
da onOptionsItemSelected()
, no
gli altri frammenti partecipanti ricevono il callback.
Nella tua implementazione di onOptionsItemSelected()
, utilizza un switch
sul itemId
della voce di menu. Se l'elemento selezionato
è tuo, gestisci il tocco in modo appropriato e restituisce true
per indicare
in cui viene gestito l'evento di clic. Se l'elemento selezionato non è
tua, chiama l'implementazione super
. Per impostazione predefinita, super
l'implementazione restituisce false
per consentire l'elaborazione del menu.
Kotlin
class ExampleFragment : Fragment() { ... override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_settings -> { // Navigate to settings screen. true } R.id.action_done -> { // Save profile changes. true } else -> super.onOptionsItemSelected(item) } } }
Java
public class ExampleFragment extends Fragment { ... @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.action_settings: { // Navigate to settings screen. return true; } case R.id.action_done: { // Save profile changes. return true; } default: return super.onOptionsItemSelected(item); } } }
Modificare in modo dinamico il menu
Posiziona la logica per nascondere o mostrare un pulsante o modificare l'icona in
onPrepareOptionsMenu()
Questo metodo viene chiamato subito prima della visualizzazione del menu.
Continuando con l'esempio precedente, il pulsante Salva dovrebbe essere
invisibile finché l'utente non inizia ad apportare modifiche e dovrebbe scomparire dopo
dall'utente. L'aggiunta di questa logica a onPrepareOptionsMenu()
rende
il menu presenta correttamente:
Kotlin
class ExampleFragment : Fragment() { ... override fun onPrepareOptionsMenu(menu: Menu){ super.onPrepareOptionsMenu(menu) val item = menu.findItem(R.id.action_done) item.isVisible = isEditing } }
Java
public class ExampleFragment extends Fragment { ... @Override public void onPrepareOptionsMenu(@NonNull Menu menu) { super.onPrepareOptionsMenu(menu); MenuItem item = menu.findItem(R.id.action_done); item.setVisible(isEditing); } }
Quando devi aggiornare il menu, ad esempio quando un utente preme il tasto
Pulsante Modifica per modificare le informazioni del profilo e la chiamata
invalidateOptionsMenu()
:
sull'attività dell'host per richiedere che il sistema effettui una chiamata a onCreateOptionsMenu()
.
Dopo l'annullamento della convalida, puoi apportare gli aggiornamenti in onCreateOptionsMenu()
. Una volta
il menu si gonfia, il sistema chiama onPrepareOptionsMenu()
e si aggiorna
il menu per riflettere lo stato attuale del frammento.
Kotlin
class ExampleFragment : Fragment() { ... fun updateOptionsMenu() { isEditing = !isEditing requireActivity().invalidateOptionsMenu() } }
Java
public class ExampleFragment extends Fragment { ... public void updateOptionsMenu() { isEditing = !isEditing; requireActivity().invalidateOptionsMenu(); } }
Barra delle app di proprietà di un frammento
Se per la maggior parte delle schermate dell'app non è necessaria una barra delle app o se
schermo richiede una barra delle app diversa dalle altre, puoi aggiungere una
Toolbar
al tuo
con il layout a frammento. Anche se puoi aggiungere un Toolbar
in qualsiasi punto del tuo
la gerarchia di visualizzazione dei frammenti, in genere la si trova all'inizio della
sullo schermo. Per utilizzare Toolbar
nel frammento, fornisci un ID e
ottenere un riferimento nel frammento, come con qualsiasi altro
vista. Puoi anche animare la barra degli strumenti utilizzando
CoordinatorLayout
i comportamenti dei modelli,
<androidx.appcompat.widget.Toolbar
android:id="@+id/myToolbar"
... />
Se utilizzi una barra delle app di proprietà di frammenti, Google consiglia di utilizzare la classe
Toolbar
direttamente le API. Non utilizzare
setSupportActionBar()
:
e le API del menu Fragment
, che sono appropriate solo per le barre delle app di proprietà delle attività.
Amplia il menu
Il metodo di convenienza Toolbar
inflateMenu(int)
prende l'ID di un
risorsa di menu come parametro. Per gonfiare una risorsa di menu XML
barra degli strumenti, passa resId
a questo metodo, come mostrato di seguito
esempio:
Kotlin
class ExampleFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { ... viewBinding.myToolbar.inflateMenu(R.menu.sample_menu) } }
Java
public class ExampleFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { ... viewBinding.myToolbar.inflateMenu(R.menu.sample_menu); } }
Per aumentare in modo artificioso un'altra risorsa di menu XML, richiama di nuovo il metodo con
resId
del nuovo menu. Le nuove voci di menu vengono aggiunte al menu e
le voci di menu esistenti non vengono modificate né rimosse.
Se vuoi sostituire il set di menu esistente, cancella il menu prima
chiamata inflateMenu(int)
con il nuovo ID menu, come mostrato di seguito
esempio:
Kotlin
class ExampleFragment : Fragment() { ... fun clearToolbarMenu() { viewBinding.myToolbar.menu.clear() } }
Java
public class ExampleFragment extends Fragment { ... public void clearToolbarMenu() { viewBinding.myToolbar.getMenu().clear() } }
Gestire gli eventi di clic
Puoi trasmettere un
OnMenuItemClickListener
direttamente sulla barra degli strumenti utilizzando
setOnMenuItemClickListener()
. Questo listener viene richiamato quando l'utente seleziona una voce di menu
dai pulsanti di azione presentati alla fine della barra degli strumenti o
overflow associato. L'elemento selezionato
MenuItem
viene passato al
onMenuItemClick()
e può essere utilizzato per consumare l'azione, come mostrato di seguito
esempio:
Kotlin
class ExampleFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { ... viewBinding.myToolbar.setOnMenuItemClickListener { when (it.itemId) { R.id.action_settings -> { // Navigate to settings screen. true } R.id.action_done -> { // Save profile changes. true } else -> false } } } }
Java
public class ExampleFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { ... viewBinding.myToolbar.setOnMenuItemClickListener(item -> { switch (item.getItemId()) { case R.id.action_settings: // Navigate to settings screen. return true; case R.id.action_done: // Save profile changes. return true; default: return false; } }); } }
Modificare in modo dinamico il menu
Se il frammento è proprietario della barra delle app, puoi modificare Toolbar
all'indirizzo
un runtime simile a quello di qualsiasi altra vista.
Continuando con l'esempio precedente, l'opzione di menu Salva dovrebbe essere invisibile finché l'utente non inizia a modificarlo e dovrebbe scomparire di nuovo quando tocchi:
Kotlin
class ExampleFragment : Fragment() { ... fun updateToolbar() { isEditing = !isEditing val saveItem = viewBinding.myToolbar.menu.findItem(R.id.action_done) saveItem.isVisible = isEditing } }
Java
public class ExampleFragment extends Fragment { ... public void updateToolbar() { isEditing = !isEditing; MenuItem saveItem = viewBinding.myToolbar.getMenu().findItem(R.id.action_done); saveItem.setVisible(isEditing); } }
Aggiungi un'icona di navigazione
Se presente, il pulsante di navigazione viene visualizzato all'inizio della barra degli strumenti.
Impostando un'icona di navigazione sulla barra degli strumenti, questa viene resa visibile. Puoi anche
imposta un onClickListener()
specifico per la navigazione che venga chiamato ogni volta
l'utente fa clic sul pulsante di navigazione, come illustrato di seguito
esempio:
Kotlin
class ExampleFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { ... myToolbar.setNavigationIcon(R.drawable.ic_back) myToolbar.setNavigationOnClickListener { view -> // Navigate somewhere. } } }
Java
public class ExampleFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { ... viewBinding.myToolbar.setNavigationIcon(R.drawable.ic_back); viewBinding.myToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Navigate somewhere. } }); } }