Mengubah adegan dengan dekorator adegan

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 Scene baru. Secara umum, adegan yang ditampilkan mengambil adegan input sebagai parameter dan memanggil metode content adegan input dalam metode content-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

    // ...
}