シーン デコレータを使用すると、アプリのシーン戦略によって計算されたシーンを変更できます。実際には、NavDisplay によって表示されるコンテンツを構築する第 2 段階で使用されます。
このアプローチでは、一般的な UI コンポーネントの表示などの特定の機能を個々のシーン デコレータにカプセル化できます。
たとえば、メールの受信トレイ、ダイレクト メッセージの受信トレイ、カレンダー ビューという 3 つのトップレベル ルートを持つ生産性向上アプリを考えてみましょう。このようなアプリでは、2 つのシーン デコレータを使用できます。1 つは、現在の最上位ルートの情報とコントロールを表示するトップ アプリバーを追加するためのもので、もう 1 つは、ルート間を移動するための永続的なナビゲーション バーまたはレールを追加するためのものです。
シーン デコレータ戦略を作成する
シーン デコレータは、シーン戦略と同様のパターンに従います。シーン デコレータを定義するには、SceneDecoratorStrategy インターフェースを実装します。このインターフェースには、SceneStrategy インターフェースの calculateScene メソッドに類似した decorateScene メソッドがあります。decorateScene は、シーンを装飾できるかどうかを決定します。
- シーン デコレータ戦略が入力シーンを装飾しない場合は、入力シーンをそのまま返します。
- 入力シーンを装飾する必要がある場合は、新しい
Sceneを返します。一般に、返されるシーンは入力シーンをパラメータとして受け取り、独自のcontentメソッド内で入力シーンのcontentメソッドを呼び出します。
入力シーンを装飾するかどうか、またどのように装飾するかを決定するために、シーン デコレータ戦略では、入力 Scene とそのシーンに含まれるエントリの両方のメタデータを考慮できます。
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() } }
シーン デコレータ戦略を使用する
シーン デコレータ戦略を使用するには、sceneDecoratorStrategies パラメータを使用して NavDisplay に指定します。シーンを装飾する際、NavDisplay は各戦略の decorateScene メソッドを連続して呼び出し、各呼び出しの出力を次の呼び出しの入力として渡します。
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
シーン デコレータの一般的なパターン
シーン デコレータを実装する際は、次の一般的なパターンに注意してください。
プロパティをコピー
多くの場合、シーンを装飾して返されるシーンには、装飾するシーンと同じエントリが含まれ、同じ前のエントリが含まれている必要があります。また、デフォルトの動作を使用するのではなく、装飾するシーンのメタデータを継承(または変更)する必要があります。次のコードは、この方法の例を示しています。
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 // ... }
アニメーションを維持する
デスティネーション間のアニメーションで詳しく説明されているように、NavDisplay は、現在のシーンのクラスとその key プロパティから派生したキーが変更されると、シーン間の遷移を自動的にアニメーション化します。
アプリにシーン デコレータを導入すると、シーン計算中に返されるシーンのクラスが変更された場合でも、シーン デコレーション後に返されるシーンのクラスは同じままになります。この場合、デコレーション シーンがデコレーション対象のシーンの key を直接コピーすると、派生キーが変更されないため、組み込みアニメーションは発生しなくなります。
組み込みのアニメーション サポートを維持するには、デコレーション シーンで、calculateScene によって返されるシーンのクラスと key から派生したキーを使用する必要があります。
data class DerivedKeyScene<T : Any>( val scene: Scene<T> ) : Scene<T> { override val key = scene::class to scene.key // ... }