Mendesain grafik navigasi

Komponen Navigation menggunakan grafik navigasi untuk mengelola navigasi aplikasi. Grafik navigasi adalah struktur data yang berisi setiap tujuan dalam aplikasi Anda dan hubungan antar-tujuan tersebut.

Jenis tujuan

Ada tiga jenis tujuan umum: dihosting, dialog, dan aktivitas. Tabel berikut menguraikan ketiga jenis tujuan ini dan tujuannya.

Jenis

Deskripsi

Kasus penggunaan

Dihosting

Mengisi seluruh host navigasi. Artinya, ukuran tujuan yang dihosting sama dengan ukuran host navigasi dan tujuan sebelumnya tidak terlihat.

Layar utama dan detail.

Dialog

Menampilkan komponen UI overlay. UI ini tidak terikat dengan lokasi host navigasi atau ukurannya. Tujuan sebelumnya terlihat di bawah tujuan.

Pemberitahuan, pilihan, formulir.

Aktivitas

Menampilkan layar atau fitur unik dalam aplikasi.

Berfungsi sebagai titik keluar ke grafik navigasi yang memulai aktivitas Android baru yang dikelola secara terpisah dari komponen Navigation.

Dalam Modern Android Development, aplikasi terdiri dari satu aktivitas. Oleh karena itu, tujuan aktivitas paling tepat digunakan saat berinteraksi dengan aktivitas pihak ketiga atau sebagai bagian dari proses migrasi.

Dokumen ini berisi contoh tujuan yang dihosting, yang merupakan tujuan paling umum dan mendasar. Lihat panduan berikut untuk mendapatkan informasi tentang tujuan lainnya:

Framework

Meskipun alur kerja umum yang sama berlaku dalam setiap kasus, cara pembuatan grafik dan host navigasi bergantung pada framework UI yang Anda gunakan.

  • Compose: Gunakan composable NavHost. Tambahkan NavGraph ke dalamnya menggunakan DSL Kotlin. Anda dapat membuat grafik dengan dua cara:
    • Sebagai bagian dari NavHost: Buat grafik navigasi secara langsung sebagai bagian dari penambahan NavHost.
    • Secara terprogram: Gunakan metode NavController.createGraph() untuk membuat NavGraph dan teruskan ke NavHost secara langsung.
  • Fragmen: Saat menggunakan fragmen dengan framework UI tampilan, gunakan NavHostFragment sebagai host. Ada beberapa cara untuk membuat grafik navigasi:
    • Secara terprogram: Gunakan DSL Kotlin untuk membuat NavGraph dan langsung menerapkannya di NavHostFragment.
      • Fungsi createGraph() yang digunakan dengan DSL Kotlin untuk fragmen dan Compose sama.
    • XML: Tulis grafik dan host navigasi secara langsung dalam XML.
    • Editor Android Studio: Gunakan editor GUI di Android Studio untuk membuat dan menyesuaikan grafik sebagai file resource XML.

Compose

Di Compose, gunakan objek atau class serializable untuk menentukan rute. Rute menjelaskan cara menuju ke tujuan, dan berisi semua informasi yang diperlukan tujuan.

Gunakan anotasi @Serializable untuk membuat metode serialisasi dan deserialisasi yang diperlukan secara otomatis untuk jenis rute Anda. Anotasi ini disediakan oleh plugin Serialisasi Kotlin. Ikuti petunjuk ini untuk menambahkan plugin ini.

Setelah menentukan rute, gunakan composable NavHost untuk membuat grafik navigasi. Perhatikan contoh berikut:

@Serializable
object Profile
@Serializable
object FriendsList

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile) {
    composable<Profile> { ProfileScreen( /* ... */ ) }
    composable<FriendsList> { FriendsListScreen( /* ... */ ) }
    // Add more destinations similarly.
}
  1. Objek yang dapat diserialisasi mewakili setiap dari dua rute, Profile dan FriendsList.
  2. Panggilan ke composable NavHost akan meneruskan NavController dan rute untuk tujuan awal.
  3. Lambda yang diteruskan ke NavHost pada akhirnya memanggil NavController.createGraph() dan menampilkan NavGraph.
  4. Setiap rute disediakan sebagai argumen jenis ke NavGraphBuilder.composable<T>() yang menambahkan tujuan ke NavGraph yang dihasilkan.
  5. Lambda yang diteruskan ke composable adalah yang ditampilkan NavHost untuk tujuan tersebut.

Memahami lambda

Untuk lebih memahami lambda yang membuat NavGraph, pertimbangkan bahwa untuk membangun grafik yang sama seperti dalam cuplikan sebelumnya, Anda dapat membuat NavGraph secara terpisah menggunakan NavController.createGraph() dan meneruskannya ke NavHost secara langsung:

val navGraph by remember(navController) {
  navController.createGraph(startDestination = Profile)) {
    composable<Profile> { ProfileScreen( /* ... */ ) }
    composable<FriendsList> { FriendsListScreen( /* ... */ ) }
  }
}
NavHost(navController, navGraph)

Meneruskan argumen

Jika Anda perlu meneruskan data ke tujuan, tentukan rute dengan class yang memiliki parameter. Misalnya, rute Profile adalah class data dengan parameter name.

@Serializable
data class Profile(val name: String)

Setiap kali Anda perlu meneruskan argumen ke tujuan tersebut, Anda membuat instance class rute, yang meneruskan argumen ke konstruktor class.

Untuk argumen opsional, buat kolom nullable dengan nilai default.

@Serializable
data class Profile(val nickname: String? = null)

Mendapatkan instance rute

Anda bisa mendapatkan instance rute dengan NavBackStackEntry.toRoute() atau SavedStateHandle.toRoute(). Saat Anda membuat tujuan menggunakan composable(), NavBackStackEntry tersedia sebagai parameter.

@Serializable
data class Profile(val name: String)

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(name = profile.name) }
}

Perhatikan hal berikut dalam cuplikan ini:

  • Rute Profile menentukan tujuan awal dalam grafik navigasi, dengan "John Smith" sebagai argumen untuk name.
  • Tujuan itu sendiri adalah blok composable<Profile>{}.
  • Composable ProfileScreen menggunakan nilai profile.name untuk argumen name-nya sendiri.
  • Dengan demikian, nilai "John Smith" akan diteruskan ke ProfileScreen.

Contoh minimal

Contoh lengkap NavController dan NavHost yang bekerja sama:

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
    profile: Profile
    onNavigateToFriendsList: () -> Unit,
  ) {
  Text("Profile for ${profile.name}")
  Button(onClick = { onNavigateToFriendsList() }) {
    Text("Go to Friends List")
  }
}

// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
  Text("Friends List")
  Button(onClick = { onNavigateToProfile() }) {
    Text("Go to Profile")
  }
}

// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = Profile(name = "John Smith")) {
    composable<Profile> { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(
            profile = profile,
            onNavigateToFriendsList = {
                navController.navigate(route = FriendsList)
            }
        )
    }
    composable<FriendsList> {
      FriendsListScreen(
        onNavigateToProfile = {
          navController.navigate(
            route = Profile(name = "Aisha Devi")
          )
        }
      )
    }
  }
}

Seperti yang ditunjukkan cuplikan, ekspos peristiwa ke NavHost, bukan meneruskan NavController ke composable Anda. Artinya, composable Anda harus memiliki parameter jenis () -> Unit yang NavHost-nya akan meneruskan lambda yang memanggil NavController.navigate().

Fragmen

Seperti diuraikan di bagian sebelumnya, saat menggunakan fragmen, Anda memiliki opsi untuk membuat grafik navigasi secara terprogram menggunakan DSL Kotlin, XML, atau editor Android Studio.

Bagian berikut menjelaskan berbagai pendekatan tersebut.

Secara terprogram

DSL Kotlin menyediakan cara terprogram untuk membuat grafik navigasi dengan fragmen. Dalam banyak hal, cara ini lebih rapi dan lebih modern daripada menggunakan file resource XML.

Pertimbangkan contoh berikut, yang menerapkan grafik navigasi dua layar.

Pertama, Anda perlu membuat NavHostFragment, yang tidak boleh menyertakan elemen app:navGraph:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

Selanjutnya, teruskan id dari NavHostFragment ke NavController.findNavController. Tindakan ini akan mengaitkan NavController dengan NavHostFragment.

Selanjutnya, panggilan ke NavController.createGraph() menautkan grafik ke NavController dan juga ke NavHostFragment:

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)

// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
    startDestination = Profile(name = "John Smith")
) {
    // Associate each destination with one of the route constants.
    fragment<ProfileFragment, Profile> {
        label = "Profile"
    }

    fragment<FriendsListFragment, FriendsList>() {
        label = "Friends List"
    }

    // Add other fragment destinations similarly.
}

Menggunakan DSL dengan cara ini sangat mirip dengan alur kerja yang diuraikan di bagian sebelumnya di Compose. Misalnya, di sana maupun di sini, fungsi NavController.createGraph() menghasilkan NavGraph. Demikian pula, meskipun NavGraphBuilder.composable() menambahkan tujuan composable ke grafik, di sini NavGraphBuilder.fragment() menambahkan tujuan fragmen.

Untuk informasi selengkapnya tentang cara menggunakan DSL Kotlin, lihat Membangun grafik dengan DSL NavGraphBuilder.

XML

Anda dapat langsung menulis XML sendiri. Contoh berikut mencerminkan dan setara dengan contoh dua layar dari bagian sebelumnya.

Pertama, buat NavHostFragment. Fragmen ini berfungsi sebagai host navigasi yang berisi grafik navigasi yang sebenarnya.

Implementasi minimal dari NavHostFragment:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navGraph="@navigation/nav_graph" />

</FrameLayout>

NavHostFragment berisi atribut app:navGraph. Gunakan atribut ini untuk menghubungkan grafik navigasi ke host navigasi. Berikut ini contoh cara menerapkan grafik:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/profile">

    <fragment
        android:id="@+id/profile"
        android:name="com.example.ProfileFragment"
        android:label="Profile">

        <!-- Action to navigate from Profile to Friends List. -->
        <action
            android:id="@+id/action_profile_to_friendslist"
            app:destination="@id/friendslist" />
    </fragment>

    <fragment
        android:id="@+id/friendslist"
        android:name="com.example.FriendsListFragment"
        android:label="Friends List" />

    <!-- Add other fragment destinations similarly. -->
</navigation>

Anda menggunakan tindakan untuk menentukan hubungan antara berbagai tujuan. Dalam contoh ini, fragmen profile berisi tindakan yang menavigasi ke friendslist. Untuk informasi selengkapnya, lihat Menggunakan tindakan dan fragmen Navigation.

Editor

Anda dapat mengelola grafik navigasi aplikasi menggunakan Navigation Editor di Android Studio. Pada dasarnya, ini adalah GUI yang dapat Anda gunakan untuk membuat dan mengedit XML NavigationFragment, seperti terlihat di bagian sebelumnya.

Untuk mengetahui informasi selengkapnya, lihat Navigation Editor.

Grafik bertingkat

Anda juga dapat menggunakan grafik bertingkat. Hal ini melibatkan penggunaan grafik sebagai tujuan navigasi. Untuk informasi selengkapnya, lihat Grafik bertingkat.

Bacaan Lebih Lanjut

Untuk konsep navigasi inti lainnya, lihat panduan berikut:

  • Ringkasan: Pastikan Anda membaca ringkasan umum tentang komponen Navigation.
  • Tujuan aktivitas: Contoh cara menerapkan tujuan yang mengarahkan pengguna ke aktivitas.
  • Tujuan dialog: Contoh cara membuat tujuan yang mengarahkan pengguna ke dialog.
  • Menavigasi ke tujuan: Panduan mendetail yang mencakup cara menavigasi dari satu tujuan ke tujuan lainnya.
  • Grafik bertingkat: Panduan mendalam tentang cara menyusun satu grafik navigasi di dalam grafik navigasi lainnya secara bertingkat.