Sahne dekoratörleriyle sahneleri değiştirme

Sahne dekoratörleri, uygulamanızın sahne stratejisi tarafından hesaplanan sahneyi değiştirmenize olanak tanır. Aslında, NavDisplay tarafından görüntülenen içeriği oluşturmanın ikinci aşaması için kullanılırlar.

Bu yaklaşım, ortak kullanıcı arayüzü bileşenlerini görüntüleme gibi belirli işlevleri ayrı sahne dekoratörlerinde kapsüllemenize olanak tanır.

Örneğin, üç üst düzey rotası olan bir üretkenlik uygulaması düşünün: 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 rota için 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 gezinme sütunu eklemek için kullanılabilir.

Sahne dekoratörü stratejisi oluşturma

Sahne dekoratörleri, sahne stratejilerine benzer bir kalıp 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 decorateScene yöntemi vardır. decorateScene, sahneyi süsleyip süsleyemeyeceğini belirler:

  • Sahne dekoratörü stratejiniz giriş sahnesini dekore etmemeliyse giriş sahnesini olduğu gibi döndürü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.

Sahne dekoratörü stratejiniz, giriş sahnesinin dekore edilip edilmeyeceğini ve nasıl dekore edileceğini belirlemek için hem giriş Scene hem de bu sahnedeki 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 sceneDecoratorStrategies parametresini kullanarak bunları NavDisplay öğ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 sonrakinin girişi olarak iletir.

NavDisplay(
    // ...
    sceneDecoratorStrategies = listOf(firstSceneDecoratorStrategy, secondSceneDecoratorStrategy)
)

Sahne dekoratörleri için yaygın kalıplar

Sahne dekoratörlerini uygularken dikkat edilmesi gereken bazı yaygın kalıplar şunlardır:

Özellikleri kopyala

Çoğu durumda, bir sahneyi süsleyerek döndürülen sahne, süslediği sahneyle aynı girişleri içermeli ve aynı önceki girişlere sahip olmalıdır. 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 verilmiştir:

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 bölümünde ayrıntılı olarak açıklandığı gibi, NavDisplay, geçerli sahnenin sınıfından türetilen bir anahtar ve key özelliği değiştiğinde sahneler arasındaki geçişleri otomatik olarak canlandırır.

Uygulamanıza sahne dekoratörleri eklerken, sahne hesaplama sırasında döndürülen sahnenin sınıfı değişse bile sahne dekorasyonundan sonra döndürülen sahnenin 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 sürdürmek için dekorasyon sahneleri, sınıftan türetilen bir anahtar ve calculateScene tarafından döndürülen sahnenin key değerini kullanmalıdır.

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

    // ...
}