Menerapkan logika atau wrapper ke tujuan

Anda dapat memberikan informasi tambahan atau menerapkan logika yang sama ke tujuan menggunakan class NavEntryDecorator. Class ini menggabungkan setiap NavEntry dalam data sebelumnya dengan fungsi composable. Dengan kata lain, fungsi ini mendekorasi konten entri.

Membuat dekorator kustom

Untuk membuat dekorator, perluas class NavEntryDecorator dan ganti metode berikut:

  • decorate - Lambda composable yang dipanggil untuk setiap NavEntry di data sebelumnya. Fungsi ini menerima NavEntry sebagai parameter. Dengan demikian, Anda dapat membuat objek status yang dikunci ke contentKey entri. Anda dapat menggunakan CompositionLocalProvider untuk menyediakan dependensi ke konten entri. Anda juga dapat mengapit konten dengan fungsi composable, atau memicu efek samping. Anda harus selalu memanggil entry.Content() di dalam metode ini.
  • onPop - Callback yang dipanggil saat NavEntry telah dihapus dari data sebelumnya dan telah keluar dari komposisi. Fungsi ini menerima contentKey dari entri yang dihapus. Gunakan contentKey untuk mengidentifikasi dan membersihkan status apa pun yang terkait dengan entri tersebut.

Contoh berikut memperluas class NavEntryDecorator untuk membuat dekorator kustom.

// import androidx.navigation3.runtime.NavEntryDecorator
class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>(
    decorate = { entry ->
        Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated")
        entry.Content()
    },
    onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") }
)

Jika dekorator Anda memerlukan akses ke status, buat fungsi composable yang membuat status tersebut, lalu gunakan untuk membuat dekorator. Untuk contoh implementasi, lihat kode sumber untuk rememberSaveableStateHolderNavEntryDecorator. Tindakan ini akan membuat status - SaveableStateHolder - dan menggunakannya untuk membuat dekorator.

Mendekorasi data sebelumnya

Setelah membuat NavEntryDecorator, hias entri di data sebelumnya dengan salah satu dari dua cara berikut:

  • Gunakan rememberDecoratedNavEntries. Fungsi ini berguna saat Anda memiliki beberapa data sebelumnya, masing-masing dengan kumpulan dekoratornya sendiri (lihat resep kode ini untuk mengetahui detail selengkapnya). Fungsi ini menampilkan daftar NavEntry yang didekorasi yang dapat Anda gunakan dengan NavDisplay.
  • Berikan dekorator Anda langsung ke NavDisplay menggunakan parameter entryDecorators. NavDisplay memanggil rememberDecoratedNavEntries di balik layar dan menampilkan entri yang didekorasi.

Menyertakan dekorator default

Navigation 3 menyertakan dekorator default bernama SaveableStateHolderNavEntryDecorator yang memungkinkan status NavEntry dipertahankan melalui perubahan konfigurasi dan penghentian proses. Fungsi ini menggabungkan konten NavEntry dengan SaveableStateProvider, yang memungkinkan panggilan rememberSaveable di dalam konten NavEntry berfungsi dengan benar.

Kecuali jika dekorator Anda menyediakan SaveableStateProvider, Anda harus menyertakan SaveableStateHolderNavEntryDecorator sebagai dekorator pertama dalam daftar dekorator yang disediakan. Objek ini dibuat menggunakan rememberSaveableStateHolderNavEntryDecorator.

Contoh:

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

Meneruskan hasil menggunakan ResultEventBusNavEntryDecorator

Mulai Navigation 3 1.2.0, Anda dapat menggunakan ResultEventBusNavEntryDecorator untuk menyediakan ResultEventBus ke setiap NavEntry menggunakan komposisi lokal LocalResultEventBus.

Secara default, rememberResultEventBusNavEntryDecorator membuat dan mengingat instance ResultEventBus-nya sendiri secara internal menggunakan rememberResultEventBus. Jika perlu mengakses bus peristiwa di luar hierarki dekorator (seperti di scaffolding aplikasi tingkat atas), Anda dapat mengangkat ResultEventBus dengan memanggil rememberResultEventBus dan meneruskannya ke rememberResultEventBusNavEntryDecorator(resultEventBus):

val resultEventBus = rememberResultEventBus()

NavDisplay(
    /* ... */
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus)
    )
)

Untuk mengetahui detail selengkapnya tentang cara mengirim dan mengamati hasil, lihat Menampilkan hasil.

Kapan harus menggunakan dekorator

Gunakan dekorator untuk:

  • Membuat dependensi untuk setiap NavEntry dalam data sebelumnya. Misalnya, ViewModelStoreNavEntryDecorator membuat ViewModelStore untuk setiap NavEntry.
  • Meneruskan hasil dan berkomunikasi antartujuan. Misalnya, ResultEventBusNavEntryDecorator menyediakan ResultEventBus ke tujuan di data sebelumnya.
  • Mencakup objek ke beberapa NavEntry. Misalnya, untuk membagikan ViewModel di antara beberapa entri.
  • Melakukan tindakan yang sama untuk beberapa NavEntry. Misalnya, untuk melakukan operasi logging, proses debug, atau pelacakan untuk setiap entri.
  • Gabungkan NavEntry dengan fungsi composable yang sama.
  • Membersihkan status yang terkait dengan NavEntry. Misalnya, saat entri dihapus dari data sebelumnya, ViewModelStoreNavEntryDecorator akan menghapus ViewModelStore terkaitnya.

Jangan gunakan dekorator untuk:

  • Teruskan dependensi ke satu NavEntry.
  • Menyediakan dependensi yang cakupannya lebih luas daripada data sebelumnya.

Dalam kedua kasus ini, teruskan dependensi secara langsung saat membuat NavEntry.

Untuk contoh kode lainnya, lihat NavEntryDecorator.