Mengonfigurasi aplikasi dengan metadata

Di Navigation 3, Anda menggunakan metadata untuk membagikan informasi arbitrer antara berbagai komponen library seperti NavEntry, Scene, dan NavDisplay. Pada tingkat yang paling dasar, metadata adalah Map<String, Any>. Namun, library ini menyediakan abstraksi tambahan untuk membuat pembacaan dan penulisan metadata menjadi lebih sederhana dan lebih aman dari segi jenis.

Memberikan metadata NavEntry

Jika aplikasi Anda membuat instance NavEntry secara langsung, berikan metadata untuk entri menggunakan parameter konstruktor metadata:

when (key) {
    is Home -> NavEntry(key, metadata = mapOf("key" to "value")) {}
}

Jika aplikasi Anda menggunakan DSL entryProvider, Anda memberikan metadata melalui parameter metadata dari fungsi entry. Ada dua overload fungsi ini: satu yang mengambil peta secara langsung dan satu lagi yang mengambil lambda yang meneruskan kunci entri sebagai argumen:

entry<Home>(metadata = mapOf("key" to "value")) { /* ... */ }
entry<Conversation>(metadata = { key: Conversation ->
    mapOf("key" to "value: ${key.id})")
}) { /* ... */ }

Memberikan metadata Scene

Secara default, Scene.metadata menggunakan pengambil kustom yang menampilkan metadata dari entri terakhir di properti entries, atau peta kosong jika itu adalah null. Saat mengimplementasikan antarmuka Scene, Anda dapat mengganti perilaku default ini sesuai kebutuhan.

Menggunakan DSL metadata

Diperkenalkan dalam rilis library 1.1.0-beta01, bahasa khusus domain (DSL) metadata menyediakan builder yang aman jenisnya untuk membuat Map<String, Any> yang digunakan untuk menyimpan metadata.

Menentukan kunci metadata

DSL mengandalkan antarmuka NavMetadataKey untuk menjaga konsistensi jenis nilai yang terkait dengan kunci metadata.

Konvensi untuk menentukan kunci metadata adalah dengan menyertakannya sebagai objek bertingkat dari class—atau, dalam kasus fungsi atau composable, objek terkait—yang akan membaca nilai yang terkait dengan kunci tersebut:

// For classes such as scene strategies or nav entry decorators, you can define the keys
// as nested object.
class MySceneStrategy<T : Any> : SceneStrategy<T> {

    // ...

    object MyStringMetadataKey : NavMetadataKey<String>
}

// An example from NavDisplay.
// Because NavDisplay is a function, the metadata keys are defined in an object with the same name.
public object NavDisplay {

    public object TransitionKey :
        NavMetadataKey<AnimatedContentTransitionScope<Scene<*>>.() -> ContentTransform>
}

Membuat metadata menggunakan DSL

Untuk membuat peta metadata, gunakan fungsi metadata, yang menggunakan parameter lambda. Dalam lambda ini, gunakan fungsi put untuk menambahkan entri ke peta menggunakan NavMetadataKey dan nilai yang sesuai.

entry<Home>(
    metadata = metadata {
        put(NavDisplay.TransitionKey) { fadeIn() togetherWith fadeOut() }
        // An additional benefit of the metadata DSL is the ability to use conditional logic
        if (condition) {
            put(MySceneStrategy.MyStringMetadataKey, "Hello, world!")
        }
    }
) {
    // ...
}

Membaca metadata menggunakan kunci metadata

DSL metadata juga menyediakan fungsi untuk menyederhanakan pembacaan metadata dengan NavMetadataKey.

// import androidx.navigation3.runtime.contains
// import androidx.navigation3.runtime.get

val hasMyString: Boolean = metadata.contains(MySceneStrategy.MyStringMetadataKey)
val myString: String? = metadata[MySceneStrategy.MyStringMetadataKey]