Mengonfigurasi aplikasi dengan metadata

Di Navigation 3, Anda menggunakan metadata untuk membagikan informasi arbitrer di antara berbagai komponen library seperti NavEntry, Scene, dan NavDisplay. Pada dasarnya, metadata adalah Map<String, Any>. Namun, library menyediakan abstraksi tambahan untuk membuat pembacaan dan penulisan metadata lebih sederhana dan lebih aman untuk jenisnya.

Menyediakan metadata NavEntry

Jika aplikasi Anda membuat instance NavEntry secara langsung, Anda memberikan 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 menggunakan peta secara langsung dan satu lagi yang menggunakan 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})")
}) { /* ... */ }

Menyediakan metadata Scene

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

Menggunakan DSL metadata

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

Menentukan kunci metadata

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

Konvensi untuk menentukan kunci metadata adalah 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>
}

Membangun 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]