แก้ไขฉากด้วย Scene Decorator

การตกแต่งฉากช่วยให้คุณแก้ไขฉากที่คำนวณโดยกลยุทธ์ฉากของแอปได้ ซึ่งจะใช้ในเฟสที่ 2 ของการสร้างเนื้อหาที่แสดงโดย NavDisplay

แนวทางนี้ช่วยให้คุณห่อหุ้มฟังก์ชันการทำงานที่เฉพาะเจาะจง เช่น การแสดง คอมโพเนนต์ UI ทั่วไป ไว้ใน Scene Decorator แต่ละรายการได้

ตัวอย่างเช่น ลองพิจารณาแอปเพิ่มประสิทธิภาพที่มีเส้นทางระดับบนสุด 3 เส้นทาง ได้แก่ กล่องจดหมายอีเมล กล่องจดหมายข้อความส่วนตัว และมุมมองปฏิทิน แอปดังกล่าวอาจใช้ ตัวตกแต่งฉาก 2 ตัว ตัวหนึ่งสำหรับเพิ่มแถบแอปด้านบนที่แสดงข้อมูลและ ตัวควบคุมสำหรับเส้นทางระดับบนสุดปัจจุบัน และอีกตัวหนึ่งสำหรับเพิ่มแถบนำทางหรือแถบนำทางถาวร เพื่อไปยังเส้นทางต่างๆ

สร้างกลยุทธ์การตกแต่งฉาก

Scene Decorator จะมีรูปแบบคล้ายกับกลยุทธ์ฉาก หากต้องการกำหนด Scene Decorator ให้ใช้SceneDecoratorStrategy อินเทอร์เฟซ อินเทอร์เฟซนี้ มีเมธอด decorateScene ซึ่งคล้ายกับเมธอด calculateScene ของอินเทอร์เฟซ SceneStrategy decorateScene จะพิจารณาว่าสามารถตกแต่งฉากได้หรือไม่

  • หากกลยุทธ์การตกแต่งฉากไม่ควรตกแต่งฉากอินพุต กลยุทธ์จะ แสดงฉากอินพุตตามเดิม
  • หากควรตกแต่งฉากอินพุต ฟังก์ชันจะแสดงผล Scene ใหม่ โดยทั่วไป ฉากที่แสดงผลจะใช้ฉากอินพุตเป็นพารามิเตอร์และเรียกใช้เมธอด content ของฉากอินพุตภายในเมธอด content ของตัวเอง

กลยุทธ์ Scene Decorator สามารถพิจารณาข้อมูลเมตาของทั้งอินพุต Scene และ รายการที่อยู่ในฉากนั้นเพื่อพิจารณาว่าควรตกแต่งฉากอินพุตหรือไม่และอย่างไร

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()
    }
}

ใช้กลยุทธ์การตกแต่งฉาก

หากต้องการใช้กลยุทธ์การตกแต่งฉาก ให้ระบุกลยุทธ์เหล่านั้นใน NavDisplay โดยใช้พารามิเตอร์ sceneDecoratorStrategies เมื่อตกแต่งฉาก NavDisplay จะเรียกใช้เมธอด decorateScene ของแต่ละกลยุทธ์ตามลำดับ โดยส่งเอาต์พุตของการเรียกใช้แต่ละครั้งเป็นอินพุตของการเรียกใช้ครั้งถัดไป

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

รูปแบบทั่วไปสำหรับเครื่องมือตกแต่งฉาก

เมื่อติดตั้งใช้งานเครื่องมือตกแต่งฉาก รูปแบบทั่วไปบางอย่างที่ควรทราบมีดังนี้

คัดลอกพร็อพเพอร์ตี้

ในหลายกรณี ฉากที่ส่งคืนโดยการตกแต่งฉากควรมีรายการเดียวกันและมีรายการก่อนหน้าเดียวกันกับฉากที่ตกแต่ง นอกจากนี้ ยังควรรับค่า (หรือแก้ไข) ข้อมูลเมตาของฉากที่ตกแต่งแทนที่จะใช้ลักษณะการทำงานเริ่มต้น โค้ดต่อไปนี้ แสดงตัวอย่างวิธีดำเนินการ

class CopyingScene<T : Any>(scene: Scene<T>) : Scene<T> {
    override val entries = scene.entries
    override val previousEntries = scene.previousEntries
    override val metadata = scene.metadata

    // ...
}

รักษาภาพเคลื่อนไหว

ดังที่อธิบายไว้ในสร้างภาพเคลื่อนไหวระหว่างปลายทาง NavDisplay จะสร้างภาพเคลื่อนไหวของการเปลี่ยนฉากโดยอัตโนมัติ เมื่อคีย์ที่ได้จากคลาสของ ฉากปัจจุบันและพร็อพเพอร์ตี้ key มีการเปลี่ยนแปลง

เมื่อนำ Scene Decorator ไปใช้ในแอป คลาสของฉากที่แสดงผลหลังการตกแต่งฉากจะยังคงเหมือนเดิมได้ แม้ว่าคลาสของฉากที่แสดงผลระหว่างการคำนวณฉากจะมีการเปลี่ยนแปลงก็ตาม เมื่อเกิดกรณีนี้และฉากตกแต่งคัดลอกkeyของฉากที่ตกแต่งโดยตรง ภาพเคลื่อนไหวในตัวจะไม่เกิดขึ้นอีกต่อไปเนื่องจากคีย์ที่ได้มาไม่เปลี่ยนแปลง

หากต้องการคงการรองรับภาพเคลื่อนไหวในตัว การตกแต่งฉากควรใช้คีย์ ที่ได้มาจากคลาสและ key ของฉากที่ calculateScene ส่งคืน

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

    // ...
}