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 Anda akan lebih mudah dipahami dan dikelola.
Selain itu, grafik bertingkat dapat digunakan kembali. Class ini juga menyediakan tingkat
enkapsulasi—tujuan di luar grafik bertingkat tidak memiliki akses langsung
ke setiap tujuan dalam grafik bertingkat. Sebaliknya, grafik akan
navigate()
ke grafik bertingkat itu sendiri, di mana logika internal dapat
berubah tanpa memengaruhi grafik lainnya.
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.
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 membawanya 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 yang ditunjukkan pada gambar 1:
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 kondisional.
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. Selanjutnya, Anda memanggil composable
dan dialog
dalam lambda
navigation
untuk menambahkan tujuan ke grafik bertingkat.
Pertimbangkan cara cuplikan berikut mengimplementasikan grafik pada gambar 2 menggunakan Compose:
NavHost(navController, startDestination = "title_screen") {
composable("title_screen") {
TitleScreen(
onPlayClicked = { navController.navigate("register") },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable("register") {
RegisterScreen(
onSignUpComplete = { navController.navigate("gameInProgress") }
)
}
navigation(startDestination = "match", route = "gameInProgress") {
composable("match") {
MatchScreen(
onStartGame = { navController.navigate("in_game") }
)
}
composable("in_game") {
InGameScreen(
onGameWin = { navController.navigate("results_winner") },
onGameLose = { navController.navigate("game_over") }
)
}
composable("results_winner") {
ResultsWinnerScreen(
onNextMatchClicked = {
navController.navigate("match") {
popUpTo("match") { inclusive = true }
}
},
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable("game_over") {
GameOverScreen(
onTryAgainClicked = {
navController.navigate("match") {
popUpTo("match") { inclusive = true }
}
}
)
}
}
}
Untuk menavigasi langsung ke tujuan bertingkat, gunakan route
seperti yang Anda lakukan
ke tujuan lainnya. Hal ini karena rute adalah konsep global yang dapat dibuka oleh
layar apa pun:
navController.navigate("match")
Fungsi ekstensi
Anda dapat menambahkan tujuan ke grafik menggunakan fungsi ekstensi di
NavGraphBuilder
. Anda dapat menggunakan fungsi ekstensi ini bersama metode ekstensi navigation
, composable
, dan dialog
bawaan.
Misalnya, Anda dapat menggunakan fungsi ekstensi untuk menambahkan grafik bertingkat yang ditunjukkan di bagian sebelumnya:
fun NavGraphBuilder.addNestedGraph(navController: NavController) {
navigation(startDestination = "match", route = "gameInProgress") {
composable("match") {
MatchScreen(
onStartGame = { navController.navigate("in_game") }
)
}
composable("in_game") {
InGameScreen(
onGameWin = { navController.navigate("results_winner") },
onGameLose = { navController.navigate("game_over") }
)
}
composable("results_winner") {
ResultsWinnerScreen(
onNextMatchClicked = { navController.navigate("match") },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable("game_over") {
GameOverScreen(
onTryAgainClicked = { navController.navigate("match") }
)
}
}
}
Anda kemudian dapat memanggil fungsi ini di lambda yang diteruskan ke NavHost
, bukan
memanggil navigasi inline. Contoh berikut menunjukkan hal tersebut:
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = "title_screen") {
composable("title_screen") {
TitleScreen(
onPlayClicked = { navController.navigate("register") },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable("register") {
RegisterScreen(
onSignUpComplete = { navController.navigate("gameInProgress") }
)
}
// Add the nested graph using the extension function
addNestedGraph(navController)
}
}
XML
Saat menggunakan XML, Anda dapat menggunakan Navigation Editor untuk membuat grafik bertingkat. Untuk melakukannya, ikuti langkah-langkah berikut:
- Di Navigation Editor, tekan dan tahan tombol Shift, lalu klik tujuan yang ingin Anda sertakan dalam grafik bertingkat.
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:
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.
Klik dua kali pada grafik bertingkat untuk menampilkan tujuannya.
Klik tab Text untuk beralih ke tampilan XML. Grafik navigasi bertingkat telah ditambahkan ke grafik. Grafik navigasi ini memiliki elemen
navigation
tersendiri bersama ID-nya sendiri dan atributstartDestination
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>
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);
Kembali ke tab Design, kembali ke grafik root dengan mengklik Root.
Merujuk grafik navigasi lain dengan include
Cara lain untuk memodularisasi struktur grafik Anda adalah menyertakan satu grafik dalam
grafik lain menggunakan elemen <include>
di grafik navigasi induk. Hal ini
memungkinkan grafik yang disertakan untuk ditentukan dalam modul terpisah atau project
sama sekali, yang memaksimalkan penggunaan kembali.
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 lainnya
Untuk mempelajari navigasi lebih lanjut, lihat referensi tambahan berikut.