場景裝飾器可讓您修改應用程式場景策略計算的場景。實際上,這些方法用於建構 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 } } } 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 // ... }
維持動畫
如「在目的地之間加上動畫效果」一文所述,當衍生自目前場景類別的索引鍵及其 key 屬性變更時,NavDisplay 會自動在場景之間加上動畫效果。
在應用程式中導入場景裝飾器時,即使場景計算期間傳回的場景類別有所變更,場景裝飾後傳回的場景類別仍可保持不變。發生這種情況時,如果裝飾場景直接複製所裝飾場景的 key,內建動畫就不會再發生,因為衍生索引鍵不會變更。
如要維持內建動畫支援,裝飾場景應使用衍生自類別的索引鍵,以及 calculateScene 傳回的場景 key。
data class DerivedKeyScene<T : Any>( val scene: Scene<T> ) : Scene<T> { override val key = scene::class to scene.key // ... }