In genere, è meglio rappresentare i flussi di accesso, le procedure guidate o altri sottoflussi all'interno dell'app come grafici di navigazione nidificati. Nidificando in questo modo i flussi di navigazione secondaria indipendenti, il flusso principale dell'interfaccia utente dell'app è più facile da comprendere e gestire.
Inoltre, i grafici nidificati sono riutilizzabili. Forniscono inoltre un livello di capsulamento: le destinazioni esterne al grafo nidificato non hanno accesso diretto alle destinazioni all'interno del grafo nidificato. Devono invece essere
navigate()
al grafico nidificato stesso, dove la logica interna può essere modificata senza influire sul resto del grafico.
Esempio
Il grafo di navigazione di primo livello della tua app deve iniziare con la destinazione iniziale visualizzata dall'utente quando avvia l'app e deve includere le destinazioni che vede mentre si sposta nella tua app.
Utilizzando come esempio il grafo di navigazione di primo livello della figura 1, supponiamo di volere richiedere all'utente di visualizzare le schermate title_screen e register solo quando l'app viene avviata per la prima volta. Successivamente, le informazioni dell'utente vengono memorizzate e, nei lanci successivi dell'app, dovresti indirizzarle direttamente alla schermata di corrispondenza.
Come best practice, imposta la schermata corrispondenza come destinazione iniziale del grafico di navigazione di primo livello e sposta le schermate di titolo e registrazione in un grafico nidificato, come mostrato nella figura 1:
Quando viene visualizzata la schermata della corrispondenza, 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 Navigazione condizionale.
Scrivi
Per creare un grafo di navigazione nidificato utilizzando Compose, utilizza la funzione
NavGraphBuilder.navigation()
. Utilizza navigation()
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 funzione lambda di navigation()
per aggiungere destinazioni al grafo 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 a una destinazione nidificata, utilizza un tipo di percorso come faresti per qualsiasi altra destinazione. Questo perché i percorsi sono un concetto globale utilizzato per identificare le destinazioni a cui è possibile accedere da 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:
- In Editor di navigazione, tieni premuto il tasto Maiusc e fai clic sulle destinazioni da includere nel grafico nidificato.
Fai clic con il tasto destro del mouse per aprire il menu contestuale e seleziona Sposta in grafico nidificato > Nuovo grafico. Le destinazioni sono racchiuse in un grafico nidificato. La figura 2 mostra un grafico nidificato in Navigation Editor:
Fai clic sul grafico nidificato. Nel riquadro Attributi vengono visualizzati i seguenti attributi:
- Tipo, che contiene "Grafo nidificato"
- ID, che contiene un ID assegnato dal sistema per il grafo nidificato. Questo ID viene utilizzato per fare riferimento al grafo nidificato dal codice.
Fai doppio clic sul grafico nidificato per visualizzarne le destinazioni.
Fai clic sulla scheda Testo per passare alla visualizzazione XML. Al grafico è stato aggiunto un grafo di navigazione nidificato. Questo grafo di navigazione ha i propri elementi
navigation
, oltre al proprio ID e a un attributostartDestination
che fa riferimento alla prima destinazione nel grafo 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 grafo radice al grafo nidificato:
Kotlin
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
Java
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- Nella scheda Design, torna al grafo principale 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 in un altro utilizzando un elemento <include>
nel grafico di navigazione principale. In questo modo, il grafo incluso può essere definito in un progetto o un modulo distinto, 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">
<strong><include app:graph="@navigation/included_graph" /></strong>
<fragment
android:id="@+id/fragment"
android:name="com.example.myapplication.BlankFragment"
android:label="Fragment in Root Graph"
tools:layout="@layout/fragment_blank">
<strong><action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" /></strong>
</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"
<strong>android:id="@+id/second_graph"</strong>
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>
Risorse aggiuntive
Per scoprire di più sulla navigazione, consulta le seguenti risorse aggiuntive.