Mit Szenendekoratoren können Sie die Szene ändern, die von der Szene
strategie Ihrer App berechnet wird. Sie werden für eine zweite Phase der Erstellung des
Inhalts verwendet, der von einem NavDisplay angezeigt wird.
Mit diesem Ansatz können Sie bestimmte Funktionen wie die Anzeige allgemeiner UI-Komponenten in einzelnen Szenendekoratoren kapseln.
Nehmen wir beispielsweise eine Produktivitäts-App mit drei Routen der obersten Ebene: einen E-Mail-Posteingang, einen Posteingang für Direktnachrichten und eine Kalenderansicht. Eine solche App könnte zwei Szenendekoratoren verwenden: einen zum Hinzufügen einer oberen App-Leiste, in der Informationen und Steuerelemente für die aktuelle Route der obersten Ebene angezeigt werden, und einen weiteren zum Hinzufügen einer dauerhaften Navigationsleiste oder eines Navigationsbereichs, um zwischen den Routen zu wechseln.
Szenendekoratorstrategie erstellen
Szenendekoratoren folgen einem ähnlichen Muster wie Szenenstrategien. Um einen Szenen
dekorator zu definieren, implementieren Sie die SceneDecoratorStrategy Schnittstelle. Diese Schnittstelle
hat eine Methode, decorateScene, die der
calculateScene Methode der SceneStrategy Schnittstelle entspricht.
decorateScene bestimmt, ob die Szene dekoriert werden kann:
- Wenn die Szenendekoratorstrategie die Eingabeszene nicht dekorieren soll, wird die Eingabeszene unverändert zurückgegeben.
- Wenn die Eingabeszene dekoriert werden soll, wird eine neue
Scenezurückgegeben. Im Allgemeinen verwendet die zurückgegebene Szene die Eingabeszene als Parameter und ruft die Methodecontentder Eingabeszene innerhalb ihrer eigenen Methodecontentauf.
Um zu bestimmen, ob und wie die Eingabeszene dekoriert werden soll, kann die Szenendekoratorstrategie die Metadaten sowohl der Eingabe-Scene als auch der Einträge in dieser Szene berücksichtigen.
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 } } } data class MyDecoratingScene<T : Any>( val scene: Scene<T> ) : Scene<T> { // ... override val content = @Composable { scene.content() } }
Szenendekoratorstrategien verwenden
Wenn Sie Szenendekoratorstrategien verwenden möchten, geben Sie sie mit dem Parameter sceneDecoratorStrategies an NavDisplay an. Beim Dekorieren von Szenen ruft NavDisplay die Methode decorateScene jeder Strategie nacheinander auf und übergibt die Ausgabe jedes Aufrufs als Eingabe an den nächsten.
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
Häufige Muster für Szenendekoratoren
Bei der Implementierung von Szenendekoratoren sollten Sie die folgenden häufigen Muster beachten:
Eigenschaften kopieren
In vielen Fällen sollte die Szene, die durch das Dekorieren einer Szene zurückgegeben wird, dieselben Einträge und dieselben vorherigen Einträge wie die Szene haben, die dekoriert wird. Außerdem sollten die Metadaten der Szene , die dekoriert wird, wahrscheinlich übernommen (oder geändert) werden, anstatt das Standardverhalten zu verwenden. Der folgende Code zeigt ein Beispiel dafür, wie Sie das tun können:
data class CopyingScene<T : Any>( val scene: Scene<T> ) : Scene<T> { override val entries = scene.entries override val previousEntries = scene.previousEntries override val metadata = scene.metadata // ... }
Animationen beibehalten
Wie unter Animationen zwischen Zielen beschrieben, NavDisplay animiert
automatisch Übergänge zwischen Szenen, wenn sich ein Schlüssel ändert, der von der Klasse der
aktuellen Szene und ihrer key Eigenschaft abgeleitet wird.
Wenn Sie Szenendekoratoren in Ihre App einführen, kann die Klasse der Szene, die nach der Szenendekoration zurückgegeben wird
, gleich bleiben, auch wenn sich die Klasse der Szene ändert
, die während der Szenenberechnung zurückgegeben wird. Wenn dies geschieht und Szenen, die dekoriert werden, den key der Szene, die sie dekorieren, direkt kopieren, werden die integrierten Animationen nicht mehr ausgeführt, da sich der abgeleitete Schlüssel nicht ändert.
Um die Unterstützung für integrierte Animationen beizubehalten, sollten Szenen, die dekoriert werden, einen Schlüssel verwenden, der von der Klasse und dem key der Szene abgeleitet wird, die von calculateScene zurückgegeben wird.
data class DerivedKeyScene<T : Any>( val scene: Scene<T> ) : Scene<T> { override val key = scene::class to scene.key // ... }
sceneDecoratorStrategies