Grafik bertingkat

Alur login, wizard, atau sub-alur lainnya dalam aplikasi biasanya direpresentasikan dengan baik sebagai grafik navigasi bertingkat. Dengan memberi tingkat alur subnavigasi mandiri dengan cara ini, alur utama UI aplikasi dapat dipahami dan dikelola dengan lebih mudah.

Selain itu, grafik bertingkat dapat digunakan kembali. Grafik tersebut juga menyediakan tingkat enkapsulasi—tujuan di luar grafik bertingkat tidak memiliki akses langsung ke tujuan mana pun dalam grafik bertingkat. Sebaliknya, grafik akan navigate() ke grafik bertingkat itu sendiri, di mana logika internal dapat diubah tanpa memengaruhi grafik lain.

Contoh

Grafik navigasi tingkat atas Anda harus dimulai dengan tujuan awal yang dilihat pengguna saat meluncurkan aplikasi dan harus menyertakan tujuan yang dilihat pengguna saat berpindah-pindah dalam aplikasi Anda.

Gambar 1. Grafik navigasi tingkat atas.

Dengan menggunakan grafik navigasi tingkat atas dari gambar 1 sebagai contoh, Anda ingin meminta pengguna untuk melihat title_screen dan layar register hanya saat aplikasi diluncurkan pertama kali. Setelah itu, informasi pengguna akan disimpan, dan pada peluncuran aplikasi berikutnya, sebaiknya Anda mengarahkan mereka langsung ke layar match.

Sebagai praktik terbaik, tetapkan layar match sebagai tujuan awal grafik navigasi tingkat atas dan pindahkan layar judul dan daftar ke dalam grafik bertingkat, seperti ditunjukkan pada gambar 1:

Gambar 2. Grafik navigasi tingkat atas kini berisi grafik bertingkat.

Saat layar pencocokan (match) diluncurkan, periksa apakah ada pengguna terdaftar. Jika pengguna tidak terdaftar, arahkan pengguna ke layar pendaftaran.

Untuk informasi selengkapnya tentang skenario navigasi bersyarat, lihat Navigasi bersyarat.

Compose

Untuk membuat grafik navigasi bertingkat menggunakan Compose, gunakan fungsi NavGraphBuilder.navigation(). Anda menggunakan navigation() seperti fungsi NavGraphBuilder.composable() dan NavGraphBuilder.dialog() saat menambahkan tujuan ke grafik.

Perbedaan utamanya adalah navigation membuat grafik bertingkat, bukan tujuan baru. Anda kemudian memanggil composable() dan dialog() dalam lambda navigation() untuk menambahkan tujuan ke grafik bertingkat.

Pertimbangkan cara cuplikan berikut mengimplementasikan grafik dalam gambar 2 menggunakan 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 }
                   }
               }
           )
       }
   }
}

Untuk menavigasi langsung ke tujuan bertingkat, gunakan jenis rute seperti yang Anda lakukan ke tujuan lainnya. Hal ini karena rute adalah konsep global yang digunakan untuk mengidentifikasi tujuan yang dapat dibuka oleh layar apa pun:

navController.navigate(route = Match)

XML

Saat menggunakan XML, Anda dapat menggunakan Navigation Editor untuk membuat grafik bertingkat. Untuk melakukannya, ikuti langkah berikut:

  1. Dalam Navigation Editor, tekan dan tahan tombol Shift, lalu klik tujuan yang ingin dimasukkan dalam grafik bertingkat.
  2. Klik kanan untuk membuka menu konteks, lalu pilih Move to Nested Graph > New Graph. Tujuan dimasukkan dalam grafik bertingkat. Gambar 2 menunjukkan grafik bertingkat dalam Navigation Editor:

    Gambar 2. Grafik bertingkat dalam Navigation Editor
  3. Klik grafik bertingkat. Atribut berikut muncul dalam panel Attributes:

    • Type, yang berisi "Grafik Bertingkat"
    • ID, yang berisi ID yang ditetapkan sistem untuk grafik bertingkat. ID ini digunakan untuk mereferensikan grafik bertingkat dari kode Anda.
  4. Klik dua kali pada grafik bertingkat untuk menampilkan tujuannya.

  5. Klik tab Text untuk beralih ke tampilan XML. Grafik navigasi bertingkat telah ditambahkan ke grafik. Grafik navigasi ini memiliki elemen navigation dengan ID-nya sendiri dan atribut startDestination yang mengarah ke tujuan pertama dalam grafik bertingkat.

    <?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. Dalam kode Anda, teruskan ID resource tindakan yang menghubungkan grafik root ke grafik bertingkat.

    kotlin

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

    java

    Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
    
  7. Kembali ke tab Design, kembali ke grafik root dengan mengklik Root.

Mereferensikan grafik navigasi lain dengan include

Cara lain untuk memodularisasi struktur grafik Anda adalah menyertakan (include) satu grafik dalam grafik lain menggunakan elemen <include> di grafik navigasi induk. Hal ini memungkinkan grafik yang disertakan ditentukan dalam modul yang terpisah atau satu project utuh, yang dapat digunakan kembali secara maksimal.

Cuplikan berikut menunjukkan cara menggunakan <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>

Referensi tambahan

Untuk mempelajari navigasi lebih lanjut, lihat referensi tambahan berikut.

Contoh

Codelab

Video