使用中繼資料設定應用程式

在 Navigation 3 中,您可以使用中繼資料在不同程式庫元件 (例如 NavEntrySceneNavDisplay) 之間共用任意資訊。最基本來說,中繼資料就是 Map<String, Any>。 不過,這個程式庫提供額外的抽象化,可簡化中繼資料的讀取和寫入作業,並提升型別安全性。

提供 NavEntry 中繼資料

如果應用程式直接建構 NavEntry 執行個體,請使用 metadata 建構函式參數提供項目的中繼資料:

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

如果應用程式使用 entryProvider DSL,請透過 entry 函式的 metadata 參數提供中繼資料。這個函式有兩個超載:一個直接採用對應項目,另一個則採用 lambda,將項目的鍵做為引數傳遞:

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

提供 Scene 中繼資料

根據預設,Scene.metadata 會使用自訂 getter,傳回 entries 屬性中最後一個項目的 metadata,如果該項目為 null,則傳回空白對應。導入 Scene 介面時,您可以視需要覆寫這項預設行為。

使用中繼資料 DSL

程式庫的 1.1.0-beta01 版本推出中繼資料網域特定語言 (DSL),提供型別安全建構工具,用於建立 Map<String, Any> 來儲存中繼資料。

定義中繼資料鍵

DSL 依賴 NavMetadataKey 介面,確保與中繼資料鍵相關聯的值類型一致。

定義中繼資料鍵的慣例是將其納入類別的巢狀物件中,或是納入相關物件 (如果是函式或可組合項),這些物件會讀取與這些鍵相關聯的值:

// 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>
}

使用 DSL 建構中繼資料

如要建立中繼資料對應,請使用 metadata 函式,該函式會採用 lambda 參數。在這個 lambda 中,使用 put 函式,透過 NavMetadataKey 和對應值將項目新增至對應。

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!")
        }
    }
) {
    // ...
}

使用中繼資料鍵讀取中繼資料

中繼資料 DSL 也提供函式,可簡化使用 NavMetadataKey 讀取中繼資料的程序。

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

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