Il componente Navigation utilizza un grafo di navigazione per gestire la navigazione dell'app. Il grafo di navigazione è una struttura di dati che contiene ogni destinazione all'interno della tua app e le connessioni tra di esse.
Tipi di destinazione
Esistono tre tipi generali di destinazioni: ospitate, di dialogo e di attività. La tabella che segue illustra questi tre tipi di destinazioni e le relative finalità.
Digitazione |
Descrizione |
Casi d'uso |
---|---|---|
In hosting |
Riempi l'intero host di navigazione. In altre parole, le dimensioni di una destinazione ospitata sono uguali a quelle dell'host di navigazione e le destinazioni precedenti non sono visibili. |
Schermate principali e di dettaglio. |
Finestra di dialogo |
Mostra i componenti dell'interfaccia utente in overlay. Questa UI non è legata alla posizione dell'host di navigazione o alle sue dimensioni. Le destinazioni precedenti sono visibili sotto la destinazione. |
Avvisi, selezioni, moduli. |
Attività |
Rappresenta schermate o funzionalità uniche all'interno dell'app. |
Serve come punto di uscita del grafico di navigazione che avvia una nuova attività Android gestita separatamente dal componente di navigazione. Nello sviluppo Android moderno, un'app è costituita da una singola attività. Le destinazioni delle attività sono quindi ideali per interagire con attività di terze parti o nell'ambito della procedura di migrazione. |
Questo documento contiene esempi di destinazioni ospitate, ovvero le destinazioni più comuni e fondamentali. Per informazioni sulle altre destinazioni, consulta le seguenti guide:
Framework
Sebbene in ogni caso si applichi lo stesso flusso di lavoro generale, la modalità esatta di creazione di un host e di un grafico di navigazione dipende dal framework dell'interfaccia utente utilizzato.
- Componi:utilizza il composable
NavHost
. Aggiungi unNavGraph
utilizzando il DSL Kotlin. Puoi creare il grafico in due modi:- Come parte di NavHost: costruisci il grafo di navigazione direttamente come parte dell'aggiunta del
NavHost
. - In modo programmatico: utilizza il metodo
NavController.createGraph()
per creare unNavGraph
e passarlo direttamente alNavHost
.
- Come parte di NavHost: costruisci il grafo di navigazione direttamente come parte dell'aggiunta del
- Fragment: quando utilizzi i frammenti con il framework UI delle visualizzazioni, utilizza un
NavHostFragment
come host. Esistono diversi modi per creare un grafo di navigazione:- In modo programmatico:utilizza il DSL Kotlin per creare un
NavGraph
e applicarlo direttamente alNavHostFragment
.- La funzione
createGraph()
utilizzata con il DSL Kotlin sia per i frammenti sia per Compose è la stessa.
- La funzione
- XML: scrivi l'host e il grafico di navigazione direttamente in XML.
- Editor di Android Studio:utilizza l'editor GUI in Android Studio per creare e modificare il grafico come file di risorsa XML.
- In modo programmatico:utilizza il DSL Kotlin per creare un
Scrivi
In Compose, utilizza un oggetto o una classe serializzabile per definire una route. Un percorso descrive come raggiungere una destinazione e contiene tutte le informazioni richieste dalla destinazione.
Utilizza l'annotazione @Serializable
per creare automaticamente i metodi di serializzazione e deserializzazione necessari per i tipi di route. Questa annotazione è fornita dal plug-in Kotlin Serialization. Segui queste
istruzioni per aggiungere questo plug-in.
Una volta definiti i percorsi, utilizza il composable NavHost
per creare il gráfo di navigazione. Considera l'esempio seguente:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- Un oggetto serializzabile rappresenta ciascuno dei due percorsi,
Profile
eFriendsList
. - La chiamata al composable
NavHost
passa unNavController
e un percorso per la destinazione di partenza. - La funzione lambda passata a
NavHost
chiamaNavController.createGraph()
e restituisce unNavGraph
. - Ogni percorso viene fornito come argomento di tipo a
NavGraphBuilder.composable<T>()
, che aggiunge la destinazione alNavGraph
risultante. - La funzione lambda passata a
composable
è ciò cheNavHost
mostra per quella destinazione.
Informazioni su lambda
Per comprendere meglio la funzione lambda che crea NavGraph
, tieni presente che per creare lo stesso grafico dello snippet precedente, puoi creare NavGraph
separatamente utilizzando NavController.createGraph()
e passarlo direttamente a NavHost
:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
Passare gli argomenti
Se devi passare dati a una destinazione, definisci il percorso con una classe che abbia parametri. Ad esempio, il percorso Profile
è una classe di dati con un parametro name
.
@Serializable
data class Profile(val name: String)
Ogni volta che devi passare argomenti a questa destinazione, crei un'istanza della classe di route, passando gli argomenti al relativo costruttore.
Per gli argomenti facoltativi, crea campi con valori null con un valore predefinito.
@Serializable
data class Profile(val nickname: String? = null)
Ottenere l'istanza della route
Puoi ottenere l'istanza del percorso con NavBackStackEntry.toRoute()
o
SavedStateHandle.toRoute()
. Quando crei una destinazione utilizzando
composable()
, NavBackStackEntry
è disponibile come parametro.
@Serializable
data class Profile(val name: String)
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(name = profile.name) }
}
Tieni presente quanto segue in questo snippet:
- La route
Profile
specifica la destinazione di partenza nel grafico di navigazione, con"John Smith"
come argomento pername
. - La destinazione stessa è il blocco
composable<Profile>{}
. - Il composable
ProfileScreen
assume il valore diprofile.name
per il proprio argomentoname
. - Di conseguenza, il valore
"John Smith"
viene trasmesso aProfileScreen
.
Esempio minimo
Un esempio completo di utilizzo combinato di NavController
e NavHost
:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
profile: Profile
onNavigateToFriendsList: () -> Unit,
) {
Text("Profile for ${profile.name}")
Button(onClick = { onNavigateToFriendsList() }) {
Text("Go to Friends List")
}
}
// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
Text("Friends List")
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = Profile(name = "John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(
profile = profile,
onNavigateToFriendsList = {
navController.navigate(route = FriendsList)
}
)
}
composable<FriendsList> {
FriendsListScreen(
onNavigateToProfile = {
navController.navigate(
route = Profile(name = "Aisha Devi")
)
}
)
}
}
}
Come dimostra lo snippet, anziché passare NavController
ai composabili, esponi un evento a NavController
.NavHost
In altre parole, i composabili devono avere un parametro di tipo () -> Unit
a cui NavHost
passa una funzione lambda che chiama NavController.navigate()
.
Frammenti
Come descritto nelle sezioni precedenti, quando utilizzi i frammenti hai la possibilità di creare un grafo di navigazione a livello di programmazione utilizzando il DSL Kotlin, XML o l'editor Android Studio.
Le sezioni seguenti descrivono in dettaglio questi diversi approcci.
In modo programmatico
Il DSL Kotlin fornisce un modo programmatico per creare un grafo di navigazione con frammenti. In molti modi, è più pulito e moderno rispetto all'utilizzo di un file di risorse XML.
Considera l'esempio seguente, che implementa un grafo di navigazione a due schermate.
Innanzitutto, è necessario creare NavHostFragment
, che non deve includere un elemento app:navGraph
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Quindi, passa il id
del NavHostFragment
a
NavController.findNavController
. In questo modo, il NavController viene associato al NavHostFragment
.
Successivamente, la chiamata a NavController.createGraph()
collega il grafico al NavController
e di conseguenza anche al NavHostFragment
:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)
// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
startDestination = Profile(name = "John Smith")
) {
// Associate each destination with one of the route constants.
fragment<ProfileFragment, Profile> {
label = "Profile"
}
fragment<FriendsListFragment, FriendsList>() {
label = "Friends List"
}
// Add other fragment destinations similarly.
}
L'utilizzo del DSL in questo modo è molto simile al flusso di lavoro descritto nella sezione precedente su Composizione. Ad esempio, sia lì che qui, la funzione NavController.createGraph()
genera NavGraph
. Analogamente, mentre
NavGraphBuilder.composable()
aggiunge destinazioni composable al grafo, qui
NavGraphBuilder.fragment()
aggiunge una destinazione del frammento.
Per ulteriori informazioni su come utilizzare il DSL Kotlin, consulta Creare un grafo con il DSL NavGraphBuilder.
XML
Puoi scrivere direttamente il codice XML. L'esempio seguente rispecchia ed è equivalente all'esempio con due schermate della sezione precedente.
Innanzitutto, crea un NavHostFragment
. che funge da host di navigazione e contiene il grafico di navigazione effettivo.
Un'implementazione minima di un NavHostFragment
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
NavHostFragment
contiene l'attributo app:navGraph
. Utilizza questo attributo per collegare il grafo di navigazione all'host di navigazione. Di seguito è riportato un
esempio di come implementare il grafico:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@id/profile">
<fragment
android:id="@+id/profile"
android:name="com.example.ProfileFragment"
android:label="Profile">
<!-- Action to navigate from Profile to Friends List. -->
<action
android:id="@+id/action_profile_to_friendslist"
app:destination="@id/friendslist" />
</fragment>
<fragment
android:id="@+id/friendslist"
android:name="com.example.FriendsListFragment"
android:label="Friends List" />
<!-- Add other fragment destinations similarly. -->
</navigation>
Utilizzi le azioni per definire le connessioni tra destinazioni diverse. In questo esempio, il frammento profile
contiene un'azione che consente di passare a friendslist
. Per ulteriori informazioni, consulta la sezione Utilizzare azioni e frammenti di navigazione.
Editor
Puoi gestire il grafo di navigazione della tua app utilizzando l'editor di navigazione in Android Studio. Si tratta essenzialmente di un'interfaccia utente grafica che puoi utilizzare per creare e modificare il tuo file XML NavigationFragment
, come illustrato nella sezione precedente.
Per ulteriori informazioni, consulta Editor di navigazione.
Grafici nidificati
Puoi anche utilizzare grafici nidificati. Ciò comporta l'utilizzo di un grafo come destinazione di navigazione. Per ulteriori informazioni, consulta la sezione Grafici nidificati.
Per approfondire
Per altri concetti di navigazione di base, consulta le seguenti guide:
- Panoramica: assicurati di leggere la panoramica generale del componente Navigation.
- Destinazioni attività: esempi di come implementare destinazioni che indirizzano l'utente alle attività.
- Destinazioni di dialogo: esempi di come creare destinazioni che indirizzano l'utente a una finestra di dialogo.
- Andare a una destinazione: una guida dettagliata che spiega come muoversi da una destinazione all'altra.
- Grafici nidificati: una guida approfondita su come nidificare un grafico di navigazione all'interno di un altro.