場景裝飾器可讓您修改應用程式場景策略計算出的場景。實際上,這些函式可用於建構 NavDisplay 顯示的內容,屬於第二階段。
這個方法可讓您將特定功能 (例如顯示常見的 UI 元件) 封裝到個別場景裝飾器中。
舉例來說,假設某個生產力應用程式有三個頂層路徑:電子郵件收件匣、即時訊息收件匣和日曆檢視畫面。這類應用程式可以使用兩個場景裝飾器,一個用於新增頂端應用程式列,顯示目前頂層路徑的資訊和控制項,另一個用於新增持續顯示的導覽列或導覽窗格,在路徑之間導覽。
建立場景裝飾器策略
場景裝飾器的模式與場景策略類似。如要定義場景裝飾器,請實作 SceneDecoratorStrategy 介面。這個介面有一個方法 decorateScene,類似於 SceneStrategy 介面的 calculateScene 方法。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 } } } class MyDecoratingScene<T : Any>(scene: Scene<T>) : Scene<T> { // ... override val content = @Composable { scene.content() } }
使用場景裝飾器策略
如要使用場景修飾符策略,請使用 sceneDecoratorStrategies 參數將策略提供給 NavDisplay。裝飾場景時,NavDisplay 會依序呼叫各項策略的 decorateScene 方法,並將每次呼叫的輸出內容做為下一次呼叫的輸入內容。
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
場景裝飾器的常見模式
實作場景裝飾器時,請注意以下常見模式:
複製屬性
在許多情況下,裝飾場景傳回的場景應包含相同的項目,且與裝飾的場景具有相同的先前項目。此外,它應該會繼承 (或修改) 所裝飾場景的中繼資料,而不是使用預設行為。以下程式碼範例示範如何執行這項操作:
class CopyingScene<T : Any>(scene: Scene<T>) : Scene<T> { override val entries = scene.entries override val previousEntries = scene.previousEntries override val metadata = scene.metadata // ... }
維持動畫效果
如「為目的地之間的轉場加上動畫效果」一文所述,當衍生自目前場景類別及其 key 屬性的鍵變更時,NavDisplay 會自動為場景之間的轉場加上動畫效果。
在應用程式中導入場景裝飾器時,即使場景計算期間傳回的場景類別有所變更,場景裝飾後傳回的場景類別仍可維持不變。如果發生這種情況,且裝飾場景直接複製裝飾場景的 key,由於衍生金鑰不會變更,內建動畫就不會再發生。
如要維持內建動畫支援,裝飾場景應使用從類別和 calculateScene 傳回的場景 key 衍生而來的鍵。
class DerivedKeyScene<T : Any>(scene: Scene<T>) : Scene<T> { override val key = scene::class to scene.key // ... }
sceneDecoratorStrategies