I flussi di accesso, le procedure guidate o altri flussi secondari all'interno dell'app sono in genere rappresentati al meglio come grafici di navigazione nidificati. Se nidifichi i flussi di sotto-navigazione autonomi in questo modo, il flusso principale dell'UI della tua app è più facile da comprendere e gestire.
Inoltre, i grafici nidificati sono riutilizzabili. Forniscono anche un livello di
incapsulamento: le destinazioni al di fuori del grafico nidificato non hanno accesso diretto
a nessuna delle destinazioni all'interno del grafico nidificato. Devono invece
navigate()
al grafico nidificato stesso, dove la logica interna può
cambiare senza influire sul resto del grafico.
Esempio
Il grafico di navigazione di primo livello della tua app deve iniziare con la destinazione iniziale che l'utente vede quando avvia l'app e deve includere le destinazioni che vede mentre si sposta nell'app.

Utilizzando come esempio il grafico di navigazione di primo livello della figura 1, supponiamo che tu voglia richiedere all'utente di visualizzare le schermate title_screen e register solo al primo avvio dell'app. Successivamente, le informazioni dell'utente vengono memorizzate e, nei lanci successivi dell'app, dovresti indirizzarlo direttamente alla schermata Partita.
Come best practice, imposta la schermata match come destinazione iniziale del grafico di navigazione di primo livello e sposta le schermate del titolo e della registrazione in un grafico nidificato, come mostrato nella figura 1:

Quando viene visualizzata la schermata della partita, controlla se è presente un utente registrato. Se l'utente non è registrato, indirizzalo alla schermata di registrazione.
Per ulteriori informazioni sugli scenari di navigazione condizionale, consulta la sezione Navigazione condizionale.
Scrivi
Per creare un grafico di navigazione nidificato utilizzando Compose, utilizza la funzione
NavGraphBuilder.navigation()
. Utilizzi navigation()
proprio come
le funzioni NavGraphBuilder.composable()
e NavGraphBuilder.dialog()
quando aggiungi destinazioni a un grafico.
La differenza principale è che navigation
crea un grafico nidificato anziché una
nuova destinazione. Poi chiami composable()
e dialog()
all'interno
della lambda di navigation()
per aggiungere le destinazioni al grafico nidificato.
Considera come il seguente snippet implementa il grafico nella figura 2 utilizzando Compose:
// Routes
@Serializable object Title
@Serializable object Register
// Route for nested graph
@Serializable object Game
// Routes inside nested graph
@Serializable object Match
@Serializable object InGame
@Serializable object ResultsWinner
@Serializable object GameOver
NavHost(navController, startDestination = Title) {
composable<Title> {
TitleScreen(
onPlayClicked = { navController.navigate(route = Register) },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<Register> {
RegisterScreen(
onSignUpComplete = { navController.navigate(route = Game) }
)
}
navigation<Game>(startDestination = Match) {
composable<Match> {
MatchScreen(
onStartGame = { navController.navigate(route = InGame) }
)
}
composable<InGame> {
InGameScreen(
onGameWin = { navController.navigate(route = ResultsWinner) },
onGameLose = { navController.navigate(route = GameOver) }
)
}
composable<ResultsWinner> {
ResultsWinnerScreen(
onNextMatchClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
},
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<GameOver> {
GameOverScreen(
onTryAgainClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
}
)
}
}
}
Per navigare direttamente verso una destinazione nidificata, utilizza un tipo di percorso come faresti per qualsiasi altra destinazione. Questo perché le route sono un concetto globale utilizzato per identificare le destinazioni a cui può accedere qualsiasi schermata:
navController.navigate(route = Match)
XML
Quando utilizzi XML, puoi utilizzare l'editor di navigazione per creare il grafico nidificato. Per farlo, segui questi passaggi:
- Nell'Editor di navigazione, tieni premuto il tasto Maiusc e fai clic sulle destinazioni che vuoi includere nel grafico nidificato.
Fai clic con il tasto destro del mouse per aprire il menu contestuale e seleziona Sposta nel grafico nidificato > Nuovo grafico. Le destinazioni sono racchiuse in un grafico nidificato. La figura 2 mostra un grafico nidificato nell'editor di navigazione:
Figura 2. Grafico nidificato nell'editor di navigazione Fai clic sul grafico nidificato. Nel riquadro Attributi vengono visualizzati i seguenti attributi:
- Tipo, che contiene "Grafico nidificato"
- ID, che contiene un ID assegnato dal sistema per il grafico nidificato. Questo ID viene utilizzato per fare riferimento al grafico nidificato dal codice.
Fai doppio clic sul grafico nidificato per visualizzare le relative destinazioni.
Fai clic sulla scheda Testo per passare alla visualizzazione XML. Al grafico è stato aggiunto un grafico di navigazione nidificato. Questo grafico di navigazione ha i propri elementi
navigation
insieme al proprio ID e a un attributostartDestination
che rimanda alla prima destinazione nel grafico nidificato:<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.cashdog.cashdog.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main" > <action android:id="@+id/action_mainFragment_to_sendMoneyGraph" app:destination="@id/sendMoneyGraph" /> <action android:id="@+id/action_mainFragment_to_viewBalanceFragment" app:destination="@id/viewBalanceFragment" /> </fragment> <fragment android:id="@+id/viewBalanceFragment" android:name="com.example.cashdog.cashdog.ViewBalanceFragment" android:label="fragment_view_balance" tools:layout="@layout/fragment_view_balance" /> <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient"> <fragment android:id="@+id/chooseRecipient" android:name="com.example.cashdog.cashdog.ChooseRecipient" android:label="fragment_choose_recipient" tools:layout="@layout/fragment_choose_recipient"> <action android:id="@+id/action_chooseRecipient_to_chooseAmountFragment" app:destination="@id/chooseAmountFragment" /> </fragment> <fragment android:id="@+id/chooseAmountFragment" android:name="com.example.cashdog.cashdog.ChooseAmountFragment" android:label="fragment_choose_amount" tools:layout="@layout/fragment_choose_amount" /> </navigation> </navigation>
Nel codice, passa l'ID risorsa dell'azione che collega il grafico radice al grafico nidificato:
Kotlin
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
Java
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- Nella scheda Progettazione, torna al grafico radice facendo clic su Radice.
Fare riferimento ad altri grafici di navigazione con include
Un altro modo per modularizzare la struttura del grafico è includere un grafico all'interno di
un altro utilizzando un elemento <include>
nel grafico di navigazione principale. Ciò
consente di definire il grafico incluso in un modulo o progetto separato, il che massimizza la riutilizzabilità.
Il seguente snippet mostra come utilizzare <include>
:
<!-- (root) nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/fragment">
<include app:graph="@navigation/included_graph" />
<fragment
android:id="@+id/fragment"
android:name="com.example.myapplication.BlankFragment"
android:label="Fragment in Root Graph"
tools:layout="@layout/fragment_blank">
<action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" />
</fragment>
...
</navigation>
<!-- included_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/second_graph"
app:startDestination="@id/includedStart">
<fragment
android:id="@+id/includedStart"
android:name="com.example.myapplication.IncludedStart"
android:label="fragment_included_start"
tools:layout="@layout/fragment_included_start" />
</navigation>