Les décorateurs de scène vous permettent de modifier la scène calculée par la stratégie de scène de votre application. En effet, ils sont utilisés pour une deuxième phase de construction du contenu affiché par un NavDisplay.
Cette approche vous permet d'encapsuler des fonctionnalités spécifiques, telles que l'affichage de composants d'interface utilisateur courants, dans des décorateurs de scène individuels.
Prenons l'exemple d'une application de productivité comportant trois routes de premier niveau : une boîte de réception d'e-mails, une boîte de réception de messages directs et une vue d'agenda. Une telle application pourrait utiliser deux décorateurs de scène : l'un pour ajouter une barre d'application supérieure qui affiche des informations et des commandes pour l'itinéraire de premier niveau actuel, et l'autre pour ajouter une barre ou un rail de navigation persistants permettant de naviguer entre les itinéraires.
Créer une stratégie de décoration de scène
Les décorateurs de scène suivent un schéma similaire à celui des stratégies de scène. Pour définir un décorateur de scène, implémentez l'interface SceneDecoratorStrategy. Cette interface comporte une méthode, decorateScene, qui est analogue à la méthode calculateScene de l'interface SceneStrategy.
decorateScene détermine s'il peut décorer la scène :
- Si votre stratégie de décoration de scène ne doit pas décorer la scène d'entrée, elle renvoie la scène d'entrée telle quelle.
- Si elle doit décorer la scène d'entrée, elle renvoie un nouveau
Scene. En général, la scène renvoyée prend la scène d'entrée comme paramètre et appelle la méthodecontentde la scène d'entrée dans sa propre méthodecontent.
Pour déterminer si et comment la scène d'entrée doit être décorée, votre stratégie de décoration de scène peut tenir compte des métadonnées de l'Scene d'entrée et des entrées contenues dans cette scène.
class MySceneDecoratorStrategy<T : Any> : SceneDecoratorStrategy<T> { override fun SceneDecoratorStrategyScope<T>.decorateScene(scene: Scene<T>): Scene<T> { // `shouldDecorate` determines if the scene should be decorated based on scene.metadata, // scene.entries.metadata, or any other relevant state. return if (shouldDecorate(scene)) { MyDecoratingScene(scene) } else { scene } } } class MyDecoratingScene<T : Any>(scene: Scene<T>) : Scene<T> { // ... override val content = @Composable { scene.content() } }
Utiliser des stratégies de décorateur de scène
Pour utiliser des stratégies de décorateur de scène, fournissez-les à votre NavDisplay à l'aide du paramètre sceneDecoratorStrategies. Lors de la décoration des scènes, NavDisplay appelle la méthode decorateScene de chaque stratégie successivement, en transmettant le résultat de chaque appel en tant qu'entrée au suivant.
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
Modèles courants pour les décorateurs de scène
Lorsque vous implémentez des décorateurs de scène, voici quelques modèles courants à connaître :
Copier les propriétés
Dans de nombreux cas, la scène renvoyée par la décoration d'une scène doit contenir les mêmes entrées et avoir les mêmes entrées précédentes que la scène qu'elle décore. De plus, il doit probablement hériter (ou modifier) les métadonnées de la scène qu'il décore, plutôt que d'utiliser le comportement par défaut. Le code suivant montre un exemple de la façon de procéder :
class CopyingScene<T : Any>(scene: Scene<T>) : Scene<T> { override val entries = scene.entries override val previousEntries = scene.previousEntries override val metadata = scene.metadata // ... }
Conserver les animations
Comme indiqué dans Animer des transitions entre les destinations, NavDisplay anime automatiquement les transitions entre les scènes lorsqu'une clé dérivée de la classe de la scène actuelle et de sa propriété key change.
Lorsque vous introduisez des décorateurs de scène dans votre application, la classe de la scène renvoyée après la décoration de scène peut rester la même, même lorsque la classe de la scène renvoyée lors du calcul de la scène change. Lorsque cela se produit et que les scènes de décoration copient directement le key de la scène qu'elles décorent, les animations intégrées ne se produisent plus, car la clé dérivée ne change pas.
Pour maintenir la prise en charge des animations intégrées, les scènes de décoration doivent utiliser une clé dérivée de la classe et key de la scène renvoyée par calculateScene.
class DerivedKeyScene<T : Any>(scene: Scene<T>) : Scene<T> { override val key = scene::class to scene.key // ... }