Configurer votre application avec des métadonnées

Dans Navigation 3, vous utilisez des métadonnées pour partager des informations arbitraires entre différents composants de la bibliothèque, tels que NavEntry, Scene et NavDisplay. Dans sa forme la plus élémentaire, une métadonnée est un Map<String, Any>. Toutefois, la bibliothèque fournit des abstractions supplémentaires pour simplifier et sécuriser la lecture et l'écriture des métadonnées.

Fournir des métadonnées NavEntry

Si votre application crée directement ses instances NavEntry, vous fournissez des métadonnées pour l'entrée à l'aide du paramètre de constructeur metadata :

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

Si votre application utilise le DSL entryProvider, vous fournissez des métadonnées via le paramètre metadata de la fonction entry. Cette fonction comporte deux surcharges : l'une qui accepte directement une carte et l'autre qui accepte un lambda qui transmet la clé de l'entrée en tant qu'argument :

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

Fournir des métadonnées Scene

Par défaut, Scene.metadata utilise un getter personnalisé qui renvoie le metadata de la dernière entrée de sa propriété entries, ou une carte vide si la valeur est null. Lorsque vous implémentez l'interface Scene, vous pouvez remplacer ce comportement par défaut si nécessaire.

Utiliser le DSL de métadonnées

Introduit dans la version 1.1.0-beta01 de la bibliothèque, le langage spécifique au domaine (DSL) des métadonnées fournit un compilateur avec sûreté de typage pour créer le Map<String, Any> utilisé pour stocker les métadonnées.

Définir des clés de métadonnées

Le DSL s'appuie sur l'interface NavMetadataKey pour assurer la cohérence du type de la valeur associée à une clé de métadonnées.

La convention pour définir les clés de métadonnées consiste à les inclure en tant qu'objets imbriqués de la classe (ou, dans le cas de fonctions ou de composables, un objet associé) qui lira les valeurs associées à ces clés :

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

Créer des métadonnées à l'aide du DSL

Pour créer une carte de métadonnées, utilisez la fonction metadata, qui accepte un paramètre lambda. Dans ce lambda, utilisez la fonction put pour ajouter des entrées à la map à l'aide d'un NavMetadataKey et de la valeur correspondante.

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

Lire des métadonnées à l'aide de clés de métadonnées

Le DSL de métadonnées fournit également des fonctions permettant de simplifier la lecture des métadonnées avec un NavMetadataKey.

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

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