Konfigurowanie aplikacji za pomocą metadanych

W bibliotece Navigation 3 metadane służą do udostępniania dowolnych informacji między różnymi komponentami biblioteki, takimi jak NavEntry, SceneNavDisplay. W najprostszym ujęciu metadane to Map<String, Any>. Biblioteka zapewnia jednak dodatkowe abstrakcje, które ułatwiają odczytywanie i zapisywanie metadanych oraz zwiększają bezpieczeństwo typów.

Dodaj metadane NavEntry

Jeśli Twoja aplikacja tworzy instancje NavEntry bezpośrednio, podaj metadane wpisu za pomocą parametru konstruktora NavEntry:metadata

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

Jeśli Twoja aplikacja używa DSL entryProvider, metadane podajesz za pomocą parametru metadata funkcji entry. Ta funkcja ma 2 przeciążenia: jedno, które przyjmuje mapę bezpośrednio, i drugie, które przyjmuje wyrażenie lambda przekazujące klucz wpisu jako argument:

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

Dodaj metadane Scene

Domyślnie Scene.metadata używa niestandardowego pobierającego, który zwraca metadata ostatniego wpisu we właściwości entries lub pustą mapę, jeśli ta właściwość ma wartość null. Podczas wdrażania interfejsu Scene możesz w razie potrzeby zastąpić to domyślne działanie.

Używanie języka DSL metadanych

Wprowadzony w 1.1.0-beta01 wersji biblioteki język DSL metadanych zapewnia bezpieczny pod względem typów konstruktor do tworzenia Map<String, Any> używanego do przechowywania metadanych.

Definiowanie kluczy metadanych

DSL korzysta z interfejsu NavMetadataKey, aby zachować spójność typu wartości powiązanej z kluczem metadanych.

Zgodnie z konwencją klucze metadanych należy definiować jako zagnieżdżone obiekty klasy lub w przypadku funkcji lub funkcji kompozycyjnych – powiązany obiekt, który będzie odczytywać wartości powiązane z tymi kluczami:

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

Tworzenie metadanych za pomocą DSL

Aby utworzyć mapę metadanych, użyj funkcji metadata, która przyjmuje parametr lambda. W tej funkcji LAMBDA użyj funkcji put, aby dodać wpisy do mapy za pomocą NavMetadataKey i odpowiedniej wartości.

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

Odczytywanie metadanych za pomocą kluczy metadanych

Język DSL metadanych udostępnia też funkcje ułatwiające odczytywanie metadanych za pomocą NavMetadataKey.

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

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