ภาพเคลื่อนไหวระหว่างปลายทาง

NavDisplay มีความสามารถในการสร้างภาพเคลื่อนไหวในตัวเพื่อสร้างการเปลี่ยนภาพที่ราบรื่น ขณะที่ผู้ใช้ไปยังส่วนต่างๆ ของแอป คุณปรับแต่งภาพเคลื่อนไหวเหล่านี้ได้ทั่วโลกสำหรับ NavDisplay หรือที่ระดับ Scene โดยใช้ข้อมูลเมตา

ทำความเข้าใจความสามารถในการสร้างภาพเคลื่อนไหวในตัว

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

ลบล้างทรานซิชันเริ่มต้น

คุณลบล้างลักษณะการทำงานของภาพเคลื่อนไหวเริ่มต้นได้โดยระบุพารามิเตอร์การเปลี่ยน ไปยัง NavDisplay

  • transitionSpec: พารามิเตอร์นี้กำหนด ContentTransform ที่จะใช้ เมื่อมีการเพิ่มเนื้อหาลงในสแต็กย้อนกลับ (เช่น เมื่อไปยังส่วนต่างๆ)
  • popTransitionSpec: พารามิเตอร์นี้กำหนด ContentTransform ที่จะใช้เมื่อนำเนื้อหาออกจากสแต็กย้อนกลับ (กล่าวคือ เมื่อไปยังส่วนต่างๆ ย้อนกลับ)
  • predictivePopTransitionSpec: พารามิเตอร์นี้กำหนด ContentTransform ที่จะใช้เมื่อป๊อปเนื้อหาโดยใช้ท่าทางสัมผัสย้อนกลับแบบคาดการณ์

ลบล้างทรานซิชันที่ระดับ Scene

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

เมื่อระบุไว้ ระบบจะใช้ทรานซิชันระดับฉากเหล่านี้แทนค่าเริ่มต้นที่เกี่ยวข้องซึ่งตั้งค่าไว้ใน NavDisplay

ข้อมูลโค้ดต่อไปนี้แสดงทั้งการเปลี่ยน NavDisplay ทั่วโลกและการลบล้างที่ระดับ NavEntry แต่ละรายการ

@Serializable
data object ScreenA : NavKey

@Serializable
data object ScreenB : NavKey

@Serializable
data object ScreenC : NavKey

class AnimatedNavDisplayActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            Scaffold { paddingValues ->

                val backStack = rememberNavBackStack(ScreenA)

                NavDisplay(
                    backStack = backStack,
                    onBack = { backStack.removeLastOrNull() },
                    entryProvider = entryProvider {
                        entry<ScreenA> {
                            ContentOrange("This is Screen A") {
                                Button(onClick = { backStack.add(ScreenB) }) {
                                    Text("Go to Screen B")
                                }
                            }
                        }
                        entry<ScreenB> {
                            ContentMauve("This is Screen B") {
                                Button(onClick = { backStack.add(ScreenC) }) {
                                    Text("Go to Screen C")
                                }
                            }
                        }
                        entry<ScreenC>(
                            metadata = metadata {
                                put(NavDisplay.TransitionKey) {
                                    // Slide new content up, keeping the old content in place underneath
                                    slideInVertically(
                                        initialOffsetY = { it },
                                        animationSpec = tween(1000)
                                    ) togetherWith ExitTransition.KeepUntilTransitionsFinished
                                }
                                put(NavDisplay.PopTransitionKey) {
                                    // Slide old content down, revealing the new content in place underneath
                                    EnterTransition.None togetherWith
                                            slideOutVertically(
                                                targetOffsetY = { it },
                                                animationSpec = tween(1000)
                                            )
                                }
                                put(NavDisplay.PredictivePopTransitionKey) {
                                    // Slide old content down, revealing the new content in place underneath
                                    EnterTransition.None togetherWith
                                            slideOutVertically(
                                                targetOffsetY = { it },
                                                animationSpec = tween(1000)
                                            )
                                }
                            }
                        ) {
                            ContentGreen("This is Screen C")
                        }
                    },
                    transitionSpec = {
                        // Slide in from right when navigating forward
                        slideInHorizontally(initialOffsetX = { it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { -it })
                    },
                    popTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    predictivePopTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    modifier = Modifier.padding(paddingValues)
                )
            }
        }
    }
}

รูปที่ 1 แอปที่มีภาพเคลื่อนไหวที่กำหนดเอง

เปลี่ยนรายการนำทางระหว่างฉาก

ในแอปที่สร้างเลย์เอาต์ที่กำหนดเองโดยใช้ฉาก คุณสามารถใส่ NavEntry ในพร็อพเพอร์ตี้ entries ของทั้ง 2 ฉากได้ในระหว่างการเปลี่ยนฉาก ภายใน NavDisplay จะตรวจสอบว่ารายการทั้งหมดแสดงในฉากอย่างน้อย 1 ฉากในเวลาใดก็ตาม ซึ่งอาจส่งผลให้การเปลี่ยนฉากไม่ราบรื่นเมื่อNavEntryที่แสดงฉากมีการเปลี่ยนแปลง หากต้องการให้รายการเคลื่อนไหวอย่างราบรื่นระหว่างฉาก คุณสามารถรวม NavDisplay ไว้ใน SharedTransitionLayout และระบุ SharedTransitionScope ให้กับ NavDisplay ตามที่แสดงในตัวอย่างต่อไปนี้

SharedTransitionLayout {
    NavDisplay(
        // ...
        sharedTransitionScope = this
    )
}