Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Menavigasi ke tujuan

Menavigasi ke tujuan dapat dilakukan menggunakan NavController, yaitu sebuah objek yang mengelola navigasi aplikasi dalam NavHost. Setiap NavHost memiliki NavController yang sesuai. NavController menyediakan beberapa cara untuk menavigasi ke tujuan, yang akan dijelaskan lebih lanjut di bagian berikut.

Untuk mengambil NavController untuk fragmen, aktivitas, atau tampilan, gunakan salah satu dari metode berikut:

Kotlin:

Java:

Setelah mendapatkan NavController, Anda dapat memanggil overload navigate() untuk menavigasi antar-tujuan. Setiap overload memberikan dukungan untuk berbagai skenario navigasi, seperti yang dijelaskan di bagian berikut.

Menggunakan Safe Args untuk menavigasi dengan keamanan jenis

Cara yang direkomendasikan untuk bernavigasi antar-tujuan adalah dengan menggunakan plugin Safe Args Gradle. Plugin ini menghasilkan class builder dan objek sederhana yang mengaktifkan navigasi yang aman jenisnya antar-tujuan. Safe Args direkomendasikan untuk menavigasi serta meneruskan data antar-tujuan.

Untuk menambahkan Safe Args ke project Anda, sertakan build.gradle berikut ke file classpath tingkat teratas Anda:

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.3.0"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

Anda juga harus menerapkan salah satu dari dua plugin yang tersedia.

Untuk menghasilkan kode bahasa Java yang sesuai bagi modul Java atau modul campuran Java dan Kotlin, tambahkan baris berikut ke file build.gradle aplikasi atau modul Anda:

apply plugin: "androidx.navigation.safeargs"

Atau, untuk menghasilkan kode Kotlin yang sesuai bagi modul khusus Kotlin, tambahkan:

apply plugin: "androidx.navigation.safeargs.kotlin"

Anda harus memiliki android.useAndroidX=true dalam file gradle.properties seperti yang dijelaskan dalam Bermigrasi ke AndroidX.

Setelah mengaktifkan Safe Args, kode yang dihasilkan berisi class dan metode untuk setiap tindakan yang Anda tentukan serta class yang terkait dengan setiap tujuan pengiriman dan penerimaan.

Safe Args menghasilkan class untuk setiap tujuan tempat asal tindakan. Nama class yang dihasilkan menambahkan "Directions" ke nama class tujuan awal. Misalnya, jika tujuan awal diberi nama SpecifyAmountFragment, class yang dihasilkan akan diberi nama SpecifyAmountFragmentDirections.

Class yang dihasilkan berisi metode statis untuk setiap tindakan yang ditentukan pada tujuan awal. Metode ini mengambil setiap parameter tindakan yang ditentukan sebagai argumen dan menampilkan objek NavDirections yang dapat langsung Anda teruskan ke navigate().

Contoh Safe Args

Sebagai contoh, asumsikan kita memiliki grafik navigasi dengan satu tindakan yang menghubungkan dua tujuan, SpecifyAmountFragment dan ConfirmationFragment. ConfirmationFragment mengambil satu parameter float yang Anda sediakan sebagai bagian dari tindakan.

Safe Args menghasilkan class SpecifyAmountFragmentDirections dengan satu metode, actionSpecifyAmountFragmentToConfirmationFragment(), dan class dalam disebut ActionSpecifyAmountFragmentToConfirmationFragment. Class dalam diperoleh dari NavDirections dan menyimpan ID tindakan dan parameter float yang terkait. Objek NavDirections yang ditampilkan ini kemudian dapat diteruskan langsung ke navigate(), seperti yang ditunjukkan dalam contoh berikut:

Kotlin

    override fun onClick(v: View) {
        val amount: Float = ...
        val action =
            SpecifyAmountFragmentDirections
                .actionSpecifyAmountFragmentToConfirmationFragment(amount)
        v.findNavController().navigate(action)
    }
    

Java

    @Override
    public void onClick(View view) {
        float amount = ...;
        action =
            SpecifyAmountFragmentDirections
                .actionSpecifyAmountFragmentToConfirmationFragment(amount);
        Navigation.findNavController(view).navigate(action);
    }
    

Untuk informasi selengkapnya tentang meneruskan data antar-tujuan dengan Safe Args, lihat Menggunakan Safe Args untuk meneruskan data dengan keamanan jenis.

Menavigasi menggunakan ID

navigate(int) mengambil ID resource dari tindakan atau tujuan. Cuplikan kode berikut menunjukkan cara menavigasi ke ViewTransactionsFragment:

Kotlin

    viewTransactionsButton.setOnClickListener { view ->
       view.findNavController().navigate(R.id.viewTransactionsAction)
    }
    

Java

    viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
        }
    });

    

Untuk tombol, Anda juga dapat menggunakan metode praktis createNavigateOnClickListener() dari class Navigation untuk menavigasi ke tujuan, seperti yang ditunjukkan pada contoh berikut:

Kotlin

    button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null))
    

Java

    button.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.next_fragment, null));
    

Untuk menangani komponen UI umum lainnya, seperti panel aplikasi atas dan navigasi bawah, lihat Mengupdate komponen UI dengan NavigationUI.

Saat Anda menentukan tindakan dalam grafik navigasi, Navigasi menghasilkan class NavAction yang sesuai, yang berisi konfigurasi yang ditentukan untuk tindakan tersebut, termasuk hal berikut:

  • Tujuan : ID resource tujuan target.
  • Argumen default : android.os.Bundle yang berisi nilai default untuk tujuan target, jika disediakan.
  • Opsi navigasi: Opsi navigasi, yang direpresentasikan sebagai NavOptions. Class ini berisi semua konfigurasi khusus untuk mentransisikan ke dan kembali dari tujuan target, termasuk konfigurasi resource animasi, perilaku yang dikeluarkan, dan apakah tujuan harus diluncurkan dalam mode single top.

Mari lihat grafik contoh yang terdiri dari dua layar beserta tindakan untuk menavigasi dari satu tempat ke tempat lain:

<?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/a">

        <fragment android:id="@+id/a"
                  android:name="com.example.myapplication.FragmentA"
                  android:label="a"
                  tools:layout="@layout/a">
            <action android:id="@+id/action_a_to_b"
                    app:destination="@id/b"
                    app:enterAnim="@anim/nav_default_enter_anim"
                    app:exitAnim="@anim/nav_default_exit_anim"
                    app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                    app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
        </fragment>

        <fragment android:id="@+id/b"
                  android:name="com.example.myapplication.FragmentB"
                  android:label="b"
                  tools:layout="@layout/b">
            <action android:id="@+id/action_b_to_a"
                    app:destination="@id/a"
                    app:enterAnim="@anim/nav_default_enter_anim"
                    app:exitAnim="@anim/nav_default_exit_anim"
                    app:popEnterAnim="@anim/nav_default_pop_enter_anim"
                    app:popExitAnim="@anim/nav_default_pop_exit_anim"
                    app:popUpTo="@+id/a"
                    app:popUpToInclusive="true"/>
        </fragment>
    </navigation>
    

Saat grafik navigasi meningkat, tindakan ini diuraikan, dan objek NavAction yang sesuai dihasilkan dengan konfigurasi yang ditentukan dalam grafik. Misalnya, action_b_to_a ditentukan saat menavigasi dari tujuan b ke tujuan a. Tindakan ini mencakup animasi beserta perilaku popTo yang menghapus semua tujuan dari backstack. Semua setelan ini ditetapkan sebagai NavOptions dan dilampirkan ke NavAction.

Untuk mengikuti NavAction ini, gunakan NavController.navigate(), yang meneruskan ID tindakan, seperti yang ditunjukkan pada contoh berikut:

Kotlin

    findNavController().navigate(R.id.action_b_to_a)
    

Java

    Navigation.findNavController(this).navigate(R.id.action_b_to_a);
    

Menavigasi menggunakan URI

Anda dapat menggunakan navigate(Uri) untuk menavigasi langsung ke tujuan deep link implisit, seperti yang ditunjukkan pada contoh berikut:

Kotlin

    val navController = findNavController()
    val deeplink = Uri.parse("android-app://androidx.navigation.app/profile")
    findNavController().navigate(deeplink)
    

Java

    Uri deeplink = Uri.parse("android-app://androidx.navigation.app/profile");
    view.findNavController().navigate(deeplink);
    

Tidak seperti navigasi yang menggunakan ID tindakan atau tujuan, Anda dapat menavigasi ke URI mana pun di grafik Anda, terlepas dari apakah tujuan itu terlihat atau tidak. Anda dapat menavigasi ke tujuan pada grafik saat ini atau tujuan pada grafik yang benar-benar berbeda.

Saat menavigasi menggunakan URI, data sebelumnya tidak disetel ulang. Ini tidak seperti navigasi deep link lain, di mana data sebelumnya diganti saat menavigasi. Namun, popUpTo dan popUpToInclusive, tetap menghapus tujuan dari data sebelumnya seolah-olah Anda telah menavigasi menggunakan ID.

Navigasi dan data sebelumnya

Android menyimpan data sebelumnya yang berisi tujuan yang telah Anda kunjungi. Tujuan pertama aplikasi Anda ditempatkan pada tumpukan saat pengguna membuka aplikasi. Setiap panggilan ke metode navigate() akan menempatkan tujuan lainnya di atas tumpukan. Mengetuk Up atau Back akan memanggil metode NavController.navigateUp() dan NavController.popBackStack(), secara berurutan, untuk menghapus (atau pop) tujuan teratas dari tumpukan.

NavController.popBackStack() menampilkan boolean yang menunjukkan apakah metode tersebut berhasil kembali ke tujuan lain atau tidak. Kasus yang paling umum terjadi saat metode ini menampilkan false adalah saat Anda mengeluarkan tujuan awal grafik secara manual.

Saat metode menampilkan false, NavController.getCurrentDestination() menampilkan null. Anda bertanggung jawab baik dalam menavigasi ke tujuan baru atau mengendalikan pop dengan memanggil finish() di Aktivitas, seperti yang ditunjukkan pada contoh berikut:

Kotlin

    ...

    if (!navController.popBackStack()) {
        // Call finish() on your Activity
        finish()
    }

    

Java

    ...

    if (!navController.popBackStack()) {
        // Call finish() on your Activity
        finish();
    }
    

popUpTo dan popUpToInclusive

Saat menavigasi menggunakan tindakan, Anda dapat mengeluarkan tujuan tambahan secara opsional dari data sebelumnya. Misalnya, jika aplikasi Anda memiliki alur login awal, saat pengguna login, Anda harus mengeluarkan semua tujuan yang terkait login dari data sebelumnya sehingga tombol Kembali tidak mengembalikan pengguna ke alur login.

Untuk mengeluarkan tujuan saat menavigasi dari satu tujuan ke tujuan lain, tambahkan atribut app:popUpTo ke elemen <action> terkait. app:popUpTo memberi tahu library Navigasi untuk mengeluarkan semua tujuan dari data sebelumnya sebagai bagian dari panggilan ke navigate(). Nilai atribut adalah ID dari tujuan terkini yang akan disimpan di tumpukan.

Anda dapat menyertakan app:popUpToInclusive="true" untuk menunjukkan bahwa tujuan yang ditentukan pada app:popUpTo juga akan dihapus dari data sebelumnya.

Contoh popUpTo: logika melingkar

Misalkan aplikasi Anda memiliki tiga tujuan—A, B, dan C— beserta tindakan yang mengarah dari A ke B, B ke C, dan C kembali ke A. Grafik navigasi yang sesuai ditunjukkan pada gambar 1:

Gambar 1. Grafik navigasi melingkar dengan tiga tujuan: A, B, dan C.

Dengan setiap tindakan navigasi, tujuan ditambahkan ke data sebelumnya. Jika Anda menavigasi secara berulang melalui alur ini, data sebelumnya akan berisi banyak rangkaian dari setiap tujuan (A, B, C, A, B, C, A, dan seterusnya). Untuk menghindari pengulangan ini, Anda dapat menentukan app:popUpTo dan app:popUpToInclusive pada tindakan yang dapat memindahkan Anda dari tujuan C ke tujuan A, seperti yang ditunjukkan pada contoh berikut:

    <fragment
        android:id="@+id/c"
        android:name="com.example.myapplication.C"
        android:label="fragment_c"
        tools:layout="@layout/fragment_c">

        <action
            android:id="@+id/action_c_to_a"
            app:destination="@id/a"
            app:popUpTo="@+id/a"
            app:popUpToInclusive="true"/>
    </fragment>
    

Setelah sampai di tujuan C, data sebelumnya akan berisi instance dari setiap tujuan (A, B, C). Saat menavigasi kembali ke tujuan A, kami juga melakukan popUpTo A, yang berarti kami menghapus tujuan B and C dari stack saat menavigasi. Dengan app:popUpToInclusive="true", kami juga mengeluarkan tujuan A pertama tersebut dari tumpukan, yang menghapusnya secara efektif. Perhatikan di sini bahwa jika Anda tidak menggunakan app:popUpToInclusive, data sebelumnya akan berisi dua instance tujuan A.