Sahne dekoratörleriyle sahneleri değiştirme

Sahne süslemeleri, uygulamanızın scene strategy tarafından hesaplanan sahneyi değiştirmenize olanak tanır. Bu öğeler, NavDisplay tarafından gösterilen içeriğin oluşturulmasının ikinci aşamasında kullanılır.

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 (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 Scene döndürür. Genel olarak, döndürülen sahne giriş sahnesini parametre olarak alır ve kendi content yöntemi içinde giriş sahnesinin content yö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şin 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
        }
    }

}

data class MyDecoratingScene<T : Any>(
    val 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:

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

    // ...
}

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 canlandırır.

Uygulamanıza sahne dekoratörleri eklerken, sahne dekorasyonundan sonra döndürülen sahnenin sınıfı, sahne hesaplaması sırasında döndürülen sahnenin sınıfı değişse bile aynı kalabilir. Bu durum gerçekleştiğinde ve dekorasyon sahneleri, dekore ettikleri sahnenin key öğesini 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.

data class DerivedKeyScene<T : Any>(
    val scene: Scene<T>
) : Scene<T> {
    override val key = scene::class to scene.key

    // ...
}