Dekorasi adegan memungkinkan Anda mengubah adegan yang dihitung oleh strategi
adegan aplikasi Anda. Pada dasarnya, objek tersebut digunakan untuk fase kedua dalam membuat
konten yang ditampilkan oleh NavDisplay.
Dengan pendekatan ini, Anda dapat merangkum fungsi tertentu, seperti menampilkan komponen UI umum, ke dalam dekorator adegan individual.
Misalnya, pertimbangkan aplikasi produktivitas yang memiliki tiga rute tingkat teratas: kotak masuk email, kotak masuk pesan langsung, dan tampilan kalender. Aplikasi tersebut dapat menggunakan dua dekorator adegan, satu untuk menambahkan panel aplikasi atas yang menampilkan informasi dan kontrol untuk rute tingkat teratas saat ini dan yang lainnya untuk menambahkan kolom samping atau menu navigasi tetap untuk berpindah antar-rute.
Membuat strategi dekorator adegan
Dekorator adegan mengikuti pola yang serupa dengan strategi adegan. Untuk menentukan dekorator
adegan, terapkan antarmuka SceneDecoratorStrategy. Antarmuka ini memiliki metode, decorateScene, yang analog dengan metode calculateScene dari antarmuka SceneStrategy.
decorateScene menentukan apakah dapat menghias adegan:
- Jika strategi dekorator adegan tidak boleh mendekorasi adegan input, strategi tersebut akan menampilkan adegan input apa adanya.
- Jika harus menghias adegan input, fungsi ini akan menampilkan
Scenebaru. Secara umum, adegan yang ditampilkan mengambil adegan input sebagai parameter dan memanggil metodecontentadegan input dalam metodecontent-nya sendiri.
Untuk menentukan apakah dan bagaimana adegan input harus dihias, strategi penghias adegan Anda dapat mempertimbangkan metadata Scene input dan entri yang ada dalam adegan tersebut.
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() } }
Menggunakan strategi dekorator adegan
Untuk menggunakan strategi dekorator adegan, berikan strategi tersebut ke NavDisplay menggunakan parameter
sceneDecoratorStrategies. Saat mendekorasi adegan, NavDisplay memanggil
metode decorateScene dari setiap strategi secara berurutan, meneruskan output
setiap panggilan sebagai input ke panggilan berikutnya.
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
Pola umum untuk dekorator adegan
Saat menerapkan dekorator adegan, berikut beberapa pola umum yang perlu diperhatikan:
Menyalin properti
Dalam banyak kasus, adegan yang ditampilkan dengan mendekorasi adegan harus berisi entri yang sama dan memiliki entri sebelumnya yang sama dengan adegan yang didekorasinya. Selain itu, kemungkinan akan mewarisi (atau mengubah) metadata adegan yang dihiasinya, bukan menggunakan perilaku default. Kode berikut menunjukkan contoh cara melakukannya:
class CopyingScene<T : Any>(scene: Scene<T>) : Scene<T> { override val entries = scene.entries override val previousEntries = scene.previousEntries override val metadata = scene.metadata // ... }
Mempertahankan animasi
Seperti yang dijelaskan dalam Menganimasikan transisi antartujuan, NavDisplay secara otomatis
menganimasikan transisi antar-scene saat kunci yang berasal dari class
scene saat ini dan properti key-nya berubah.
Saat memperkenalkan dekorator adegan ke aplikasi Anda, class adegan yang ditampilkan setelah dekorasi adegan dapat tetap sama, meskipun class adegan yang ditampilkan selama penghitungan adegan berubah. Jika hal ini terjadi dan
adegan dekorasi menyalin key adegan yang didekorasinya secara langsung, animasi bawaan tidak akan terjadi lagi karena kunci turunan tidak berubah.
Untuk mempertahankan dukungan animasi bawaan, mendekorasi adegan harus menggunakan kunci yang berasal dari class dan key adegan yang ditampilkan oleh calculateScene.
class DerivedKeyScene<T : Any>(scene: Scene<T>) : Scene<T> { override val key = scene::class to scene.key // ... }