Verschachtelte Grafiken

Anmeldeabläufe, Assistenten oder andere untergeordnete Abläufe innerhalb Ihrer Anwendung werden normalerweise am besten als verschachtelte Navigationsgrafiken dargestellt. Wenn du eigenständige Subnavigationsabläufe auf diese Weise verschachtelst, lässt sich der Hauptablauf der UI deiner App leichter verstehen und verwalten.

Außerdem sind verschachtelte Grafiken wiederverwendbar. Sie bieten außerdem eine Kapselungsebene: Ziele außerhalb der verschachtelten Grafik haben keinen direkten Zugriff auf eines der Ziele innerhalb der verschachtelten Grafik. Stattdessen sollten sie mit navigate() an die verschachtelte Grafik selbst übergeben werden, sodass sich die interne Logik ändern kann, ohne den Rest der Grafik zu beeinträchtigen.

Beispiel

Die Navigationsgrafik auf der obersten Ebene Ihrer App sollte mit dem anfänglichen Ziel beginnen, das der Nutzer beim Starten der App sieht. Außerdem sollte es die Ziele enthalten, die der Nutzer während der Navigation in der App sieht.

Abbildung 1: Ein Navigationsdiagramm der obersten Ebene.

Nehmen wir als Beispiel die Navigationsgrafik der obersten Ebene aus Abbildung 1. Angenommen, der Nutzer soll die Bildschirme title_screen und register nur dann sehen können, wenn die App zum ersten Mal gestartet wird. Danach werden die Nutzerinformationen gespeichert. Bei nachfolgenden Starts der App sollten Sie den Nutzer direkt zum Match-Bildschirm weiterleiten.

Es hat sich bewährt, den Übereinstimmungsbildschirm als Startziel der Navigationsgrafik auf der obersten Ebene festzulegen und den Titel- und Registrierungsbildschirm in ein verschachteltes Diagramm zu verschieben, wie in Abbildung 1 dargestellt:

Abbildung 2: Die Navigationsgrafik der obersten Ebene enthält jetzt eine verschachtelte Grafik.

Prüfen Sie auf dem Bildschirm für die Zuordnung, ob ein registrierter Nutzer vorhanden ist. Wenn der Nutzer nicht registriert ist, rufe den Registrierungsbildschirm auf.

Weitere Informationen zu Szenarien der bedingten Navigation finden Sie unter Bedingte Navigation.

Textvorschläge

Verwenden Sie die Funktion NavGraphBuilder.navigation(), um mit Compose ein verschachteltes Navigationsdiagramm zu erstellen. Sie verwenden navigation() auf dieselbe Weise wie die Funktionen NavGraphBuilder.composable() und NavGraphBuilder.dialog(), um einem Diagramm Ziele hinzuzufügen.

Der Hauptunterschied besteht darin, dass navigation anstelle eines neuen Ziels eine verschachtelte Grafik erstellt. Anschließend rufen Sie composable() und dialog() in der Lambda-Funktion von navigation() auf, um dem verschachtelten Diagramm Ziele hinzuzufügen.

Im folgenden Snippet wird das Diagramm in Abbildung 2 mithilfe von Composer 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 navigieren möchten, verwenden Sie einen Routentyp genau wie zu jedem anderen Ziel. Dies liegt daran, dass Routen ein globales Konzept sind, mit dem Ziele identifiziert werden, zu denen jeder Bildschirm aufrufen kann:

navController.navigate(route = Match)

XML

Bei Verwendung von XML können Sie mit dem Navigations-Editor Ihre verschachtelte Grafik erstellen. Gehen Sie dazu folgendermaßen vor:

  1. Halten Sie im Navigationseditor die Umschalttaste gedrückt und klicken Sie auf die Ziele, die in der verschachtelten Grafik enthalten sein sollen.
  2. Klicken Sie mit der rechten Maustaste, um das Kontextmenü zu öffnen, und wählen Sie In verschachtelte Grafik verschieben > Neue Grafik aus. Die Ziele sind in einer verschachtelten Grafik eingeschlossen. Abbildung 2 zeigt ein verschachteltes Diagramm im Navigationseditor:

    Abbildung 2. Verschachteltes Diagramm im Navigationseditor
  3. Klicken Sie auf die verschachtelte Grafik. Die folgenden Attribute werden im Bereich Attribute angezeigt:

    • Typ, der „Verschachtelte Grafik“ enthält
    • ID, die eine vom System zugewiesene ID für die verschachtelte Grafik enthält. Diese ID wird verwendet, um aus Ihrem Code auf die verschachtelte Grafik zu verweisen.
  4. Doppelklicken Sie auf die verschachtelte Grafik, um ihre Ziele anzuzeigen.

  5. Klicken Sie auf den Tab Text, um zur XML-Ansicht zu wechseln. Der Grafik wurde eine verschachtelte Navigationsgrafik hinzugefügt. Diese Navigationsgrafik hat eigene navigation-Elemente sowie eine eigene ID und ein startDestination-Attribut, das auf das erste Ziel in der verschachtelten Grafik 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>
    
  6. Übergeben Sie in Ihrem Code die Ressourcen-ID der Aktion, die die Stammgrafik mit der verschachtelten Grafik verbindet:

    Kotlin

    view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
    

    Java

    Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
    
  7. Kehren Sie auf dem Tab Design zur Stammgrafik zurück, indem Sie auf Root klicken.

Mit „Einschließen“ auf andere Navigationsdiagramme verweisen

Eine weitere Möglichkeit zur Modularisierung der Diagrammstruktur besteht darin, ein Diagramm in ein anderes zu einschließen, indem Sie im übergeordneten Navigationsdiagramm ein <include>-Element verwenden. Dadurch kann die enthaltene Grafik insgesamt 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>

Zusätzliche Ressourcen

Weitere Informationen zur Navigation finden Sie in den folgenden Ressourcen.

Produktproben

Codelabs

Videos