Anmeldeabläufe, Assistenten oder andere Teilabläufe in Ihrer App werden in der Regel am besten als verschachtelte Navigationsgrafiken dargestellt. Wenn Sie auf diese Weise eigenständige Navigationsabläufe verschachteln, ist der Hauptablauf der Benutzeroberfläche Ihrer App leichter zu verstehen und zu verwalten.
Außerdem können verschachtelte Grafiken wiederverwendet werden. Außerdem bieten sie eine gewisse Kapselung: Ziele außerhalb des verschachtelten Graphen haben keinen direkten Zugriff auf die Ziele innerhalb des verschachtelten Graphen. Stattdessen sollten sie navigate()
auf das verschachtelte Diagramm selbst anwenden, da sich die interne Logik ändern kann, ohne den Rest des Diagramms zu beeinflussen.
Verwendungsbeispiele
Das Navigationsdiagramm der obersten Ebene Ihrer App sollte mit dem ursprünglichen Ziel beginnen, das der Nutzer beim Starten der App sieht, und die Ziele enthalten, die er beim Navigieren in Ihrer App sieht.
Angenommen, Sie möchten, dass die Bildschirme title_screen und register nur beim ersten Start der App angezeigt werden. Anschließend werden die Nutzerinformationen gespeichert. Bei nachfolgenden Starts der App sollten Sie die Nutzer direkt zum Bildschirm Match weiterleiten.
Als Best Practice sollten Sie den Bildschirm Match als Startziel des Navigationsdiagramms der obersten Ebene festlegen und die Bildschirme „Titel“ und „Registrieren“ in ein verschachteltes Diagramm verschieben, wie in Abbildung 1 dargestellt:
Prüfen Sie, ob auf dem Abgleichsbildschirm ein registrierter Nutzer angezeigt wird. Wenn der Nutzer nicht registriert ist, rufe den Registrierungsbildschirm auf.
Weitere Informationen zu Szenarien für die bedingte Navigation finden Sie unter Bedingte Navigation.
Schreiben
Verwenden Sie die Funktion NavGraphBuilder.navigation()
, um mit Compose ein verschachteltes Navigationsdiagramm zu erstellen. Sie verwenden navigation()
genau wie die Funktionen NavGraphBuilder.composable()
und NavGraphBuilder.dialog()
, wenn Sie einer Grafik Ziele hinzufügen.
Der Hauptunterschied besteht darin, dass mit navigation
ein verschachteltes Diagramm statt eines neuen Ziels erstellt wird. Anschließend rufen Sie composable()
und dialog()
innerhalb des Lambda-Codes von navigation()
auf, um dem verschachtelten Graphen Ziele hinzuzufügen.
Im folgenden Snippet wird die Grafik in Abbildung 2 mit Compose implementiert:
// 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 }
}
}
)
}
}
}
Wenn Sie direkt zu einem verschachtelten Ziel wechseln möchten, verwenden Sie einen Routentyp wie bei jedem anderen Ziel. Das liegt daran, dass Routen ein globales Konzept sind, mit dem Ziele identifiziert werden, zu denen von jedem Bildschirm aus navigiert werden kann:
navController.navigate(route = Match)
XML
Wenn Sie XML verwenden, können Sie das verschachtelte Diagramm mit dem Navigationseditor erstellen. Gehen Sie dazu so vor:
- Halten Sie im Navigationseditor die Umschalttaste gedrückt und klicken Sie auf die Ziele, die Sie in den verschachtelten Graphen aufnehmen möchten.
Klicken Sie mit der rechten Maustaste, um das Kontextmenü zu öffnen, und wählen Sie In verschachtelten Graphen verschieben > Neuer Graph aus. Die Ziele sind in einem verschachtelten Diagramm enthalten. Abbildung 2 zeigt ein verschachteltes Diagramm im Navigationseditor:
Klicken Sie auf das verschachtelte Diagramm. Die folgenden Attribute werden im Bereich Attribute angezeigt:
- Typ, der „Verschachtelter Graph“ enthält
- ID: Enthält eine systemzugewiesene ID für den verschachtelten Graphen. Diese ID wird verwendet, um in Ihrem Code auf die verschachtelte Grafik zu verweisen.
Klicken Sie doppelt auf das verschachtelte Diagramm, um die Ziele zu sehen.
Klicken Sie auf den Tab Text, um zur XML-Ansicht zu wechseln. Dem Diagramm wurde ein verschachteltes Navigationsdiagramm hinzugefügt. Dieses Navigationsdiagramm hat eigene
navigation
-Elemente sowie eine eigene ID und einstartDestination
-Attribut, das auf das erste Ziel im verschachtelten Diagramm verweist:<?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>
Übergeben Sie in Ihrem Code die Ressourcen-ID der Aktion, die den Stammgraphen mit dem verschachtelten Graphen verbindet:
Kotlin
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
Java
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- Kehren Sie auf dem Tab Design zum Stammdiagramm zurück, indem Sie auf Stamm klicken.
Mit „include“ auf andere Navigationsgrafiken verweisen
Eine weitere Möglichkeit, Ihre Diagrammstruktur zu modularisieren, besteht darin, ein Diagramm in ein anderes einzufügen. Verwenden Sie dazu ein <include>
-Element im übergeordneten Navigationsdiagramm. So kann der enthaltene Graph in einem separaten Modul oder Projekt definiert werden, was die Wiederverwendbarkeit maximiert.
Das folgende Snippet zeigt, wie Sie <include>
verwenden können:
<!-- (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>
Weitere Informationen
Weitere Informationen zur Navigation finden Sie in den folgenden zusätzlichen Ressourcen.