Sahne süslemeleri, uygulamanızın scene
strategy tarafından hesaplanan sahneyi değiştirmenize olanak tanır. Bu nedenle, NavDisplay tarafından gösterilen içeriğin oluşturulmasının ikinci aşamasında kullanılırlar.
Bu yaklaşım, ortak kullanıcı arayüzü bileşenlerini gösterme gibi belirli işlevleri ayrı sahne dekoratörleri içinde kapsamanıza olanak tanır.
Örneğin, üç üst düzey rotası olan bir üretkenlik uygulamasını ele alalım: e-posta gelen kutusu, doğrudan mesaj gelen kutusu ve takvim görünümü. Böyle bir uygulama, iki sahne dekoratörü kullanabilir. Bunlardan biri, mevcut üst düzey rotayla ilgili bilgileri ve kontrolleri gösteren bir üst uygulama çubuğu eklemek, diğeri ise rotalar arasında gezinmek için kalıcı bir gezinme çubuğu veya ray eklemek için kullanılır.
Sahne dekoratörü stratejisi oluşturma
Sahne süslemeleri, sahne stratejilerine benzer bir kalıbı izler. Sahne dekoratörü tanımlamak için SceneDecoratorStrategy arayüzünü uygulayın. Bu arayüzde, SceneStrategy arayüzünün calculateScene yöntemine benzer bir yöntem olan decorateScene bulunur.
decorateScene, sahneyi süsleyip süsleyemeyeceğini belirler:
- Sahne dekoratörü stratejiniz giriş sahnesini dekore etmemeliyse giriş sahnesi olduğu gibi döndürülür.
- Giriş sahnesini süslemesi gerekiyorsa yeni bir
Scenedöndürür. Genel olarak, döndürülen sahne, giriş sahnesini parametre olarak alır ve kendicontentyöntemi içinde giriş sahnesinincontentyöntemini çağırır.
Giriş sahnesinin süslenip süslenmeyeceğini ve nasıl süsleneceğini belirlemek için sahne süsleme stratejiniz hem giriş Scene hem de bu sahnede yer alan girişlerin meta verilerini dikkate alabilir.
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() } }
Sahne dekoratörü stratejilerini kullanma
Sahne dekoratörü stratejilerini kullanmak için bunları NavDisplay parametresini kullanarak sceneDecoratorStrategies öğenize sağlayın. Sahneleri dekore ederken NavDisplay, her stratejinin decorateScene yöntemini sırayla çağırır ve her çağrının çıkışını bir sonraki çağrının girişi olarak iletir.
NavDisplay( // ... sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy) )
Sahne dekoratörleri için yaygın kalıplar
Sahne dekoratörleri uygulanırken dikkat edilmesi gereken bazı yaygın desenler şunlardır:
Özellikleri kopyalama
Çoğu durumda, bir sahneyi süsleyerek döndürülen sahne, süslediği sahneyle aynı girişleri ve aynı önceki girişleri içermelidir. Ayrıca, varsayılan davranışı kullanmak yerine, süslediği sahnenin meta verilerini devralması (veya değiştirmesi) gerekir. Aşağıdaki kodda bunun nasıl yapılacağına dair bir örnek gösterilmektedir:
class CopyingScene<T : Any>(scene: Scene<T>) : Scene<T> { override val entries = scene.entries override val previousEntries = scene.previousEntries override val metadata = scene.metadata // ... }
Animasyonları koruma
Hedefler arasında animasyon oluşturma başlıklı makalede ayrıntılı olarak açıklandığı gibi, NavDisplay, mevcut sahnenin sınıfından ve key özelliğinden türetilen bir anahtar değiştiğinde sahneler arasındaki geçişleri otomatik olarak animasyonlandırır.
Uygulamanıza sahne dekoratörleri eklerken, sahne hesaplaması sırasında döndürülen sahne sınıfı değişse bile sahne dekorasyonundan sonra döndürülen sahne sınıfı aynı kalabilir. Bu durumda ve dekorasyon sahneleri, dekore ettikleri sahnenin key değerini doğrudan kopyaladığında, türetilmiş anahtar değişmediği için yerleşik animasyonlar artık gerçekleşmez.
Yerleşik animasyon desteğini korumak için sahneleri süslerken sınıftan türetilmiş bir anahtar ve calculateScene tarafından döndürülen sahnenin key değeri kullanılmalıdır.
class DerivedKeyScene<T : Any>(scene: Scene<T>) : Scene<T> { override val key = scene::class to scene.key // ... }