Compose มาพร้อมกับ Composable และตัวแก้ไขในตัวสําหรับจัดการ Use Case ของภาพเคลื่อนไหวทั่วไป
Composables ที่เคลื่อนไหวได้ในตัว
สร้างภาพเคลื่อนไหวให้วัตถุปรากฏและหายไปด้วย AnimatedVisibility

Composable
AnimatedVisibility
จะเคลื่อนไหวการปรากฏและหายไปของเนื้อหา
var visible by remember { mutableStateOf(true) } // Animated visibility will eventually remove the item from the composition once the animation has finished. AnimatedVisibility(visible) { // your composable here // ... }
โดยค่าเริ่มต้น เนื้อหาจะปรากฏโดยการค่อยๆ แสดงและขยาย และจะหายไปโดยการค่อยๆ จางและหด คุณปรับแต่งการเปลี่ยนฉากได้โดยระบุ
EnterTransition
และ
ExitTransition
var visible by remember { mutableStateOf(true) } val density = LocalDensity.current AnimatedVisibility( visible = visible, enter = slideInVertically { // Slide in from 40 dp from the top. with(density) { -40.dp.roundToPx() } } + expandVertically( // Expand from the top. expandFrom = Alignment.Top ) + fadeIn( // Fade in with the initial alpha of 0.3f. initialAlpha = 0.3f ), exit = slideOutVertically() + shrinkVertically() + fadeOut() ) { Text( "Hello", Modifier .fillMaxWidth() .height(200.dp) ) }
ดังที่เห็นในตัวอย่างด้านบน คุณสามารถรวมออบเจ็กต์ EnterTransition
หรือ ExitTransition
หลายรายการกับตัวดำเนินการ +
และแต่ละรายการจะยอมรับพารามิเตอร์ที่ไม่บังคับ
เพื่อปรับแต่งลักษณะการทำงานของออบเจ็กต์ ดูข้อมูลเพิ่มเติมได้ในแหล่งอ้างอิง
ตัวอย่าง EnterTransition
และ ExitTransition
นอกจากนี้ AnimatedVisibility
ยังมีตัวแปรที่ใช้
MutableTransitionState
ซึ่งจะช่วยให้คุณทริกเกอร์ภาพเคลื่อนไหวได้ทันทีที่เพิ่ม
AnimatedVisibility
ลงในโครงสร้างการจัดองค์ประกอบ นอกจากนี้ยังเป็นประโยชน์สำหรับ
การสังเกตสถานะภาพเคลื่อนไหวด้วย
// Create a MutableTransitionState<Boolean> for the AnimatedVisibility. val state = remember { MutableTransitionState(false).apply { // Start the animation immediately. targetState = true } } Column { AnimatedVisibility(visibleState = state) { Text(text = "Hello, world!") } // Use the MutableTransitionState to know the current animation state // of the AnimatedVisibility. Text( text = when { state.isIdle && state.currentState -> "Visible" !state.isIdle && state.currentState -> "Disappearing" state.isIdle && !state.currentState -> "Invisible" else -> "Appearing" } ) }
ภาพเคลื่อนไหวสำหรับการเข้าและออกสำหรับเด็ก
เนื้อหาภายใน AnimatedVisibility
(องค์ประกอบย่อยโดยตรงหรือโดยอ้อม) สามารถใช้ตัวแก้ไข
animateEnterExit
เพื่อระบุลักษณะการทำงานของภาพเคลื่อนไหวที่แตกต่างกันสำหรับแต่ละรายการ ภาพ
เอฟเฟกต์สำหรับแต่ละองค์ประกอบย่อยเหล่านี้คือการรวมภาพเคลื่อนไหวที่ระบุ
ไว้ใน AnimatedVisibility
Composable กับภาพเคลื่อนไหวเข้าและ
ออกขององค์ประกอบย่อยเอง
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // Fade in/out the background and the foreground. Box( Modifier .fillMaxSize() .background(Color.DarkGray) ) { Box( Modifier .align(Alignment.Center) .animateEnterExit( // Slide in/out the inner box. enter = slideInVertically(), exit = slideOutVertically() ) .sizeIn(minWidth = 256.dp, minHeight = 64.dp) .background(Color.Red) ) { // Content of the notification… } } }
ในบางกรณี คุณอาจต้องการให้ AnimatedVisibility
ไม่ใช้ภาพเคลื่อนไหวเลย เพื่อให้องค์ประกอบย่อยแต่ละรายการมีภาพเคลื่อนไหวของตัวเองที่แตกต่างกันโดยใช้ animateEnterExit
หากต้องการดำเนินการนี้ ให้ระบุ EnterTransition.None
และ
ExitTransition.None
ที่ AnimatedVisibility
ที่ใช้ร่วมกันได้
เพิ่มภาพเคลื่อนไหวที่กำหนดเอง
หากต้องการเพิ่มเอฟเฟกต์ภาพเคลื่อนไหวที่กำหนดเองนอกเหนือจากภาพเคลื่อนไหวเข้าและออกในตัว
ให้เข้าถึงอินสแตนซ์ Transition
ที่อยู่เบื้องหลังผ่านพร็อพเพอร์ตี้ transition
ภายใน Lambda ของเนื้อหาสำหรับ AnimatedVisibility
สถานะภาพเคลื่อนไหว
ที่เพิ่มลงในอินสแตนซ์การเปลี่ยนจะทำงานพร้อมกับภาพเคลื่อนไหวเข้า
และออกของ AnimatedVisibility
AnimatedVisibility
จะรอจนกว่า
ภาพเคลื่อนไหวทั้งหมดใน Transition
จะเสร็จสิ้นก่อนจึงจะนำเนื้อหาออก
สำหรับภาพเคลื่อนไหวขาออกที่สร้างขึ้นโดยไม่ขึ้นอยู่กับ Transition
(เช่น การใช้
animate*AsState
) AnimatedVisibility
จะไม่สามารถพิจารณาภาพเคลื่อนไหวเหล่านั้นได้
และอาจนำเนื้อหาที่สามารถจัดองค์ประกอบออกก่อนที่ภาพเคลื่อนไหวจะสิ้นสุด
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // this: AnimatedVisibilityScope // Use AnimatedVisibilityScope#transition to add a custom animation // to the AnimatedVisibility. val background by transition.animateColor(label = "color") { state -> if (state == EnterExitState.Visible) Color.Blue else Color.Gray } Box( modifier = Modifier .size(128.dp) .background(background) ) }
ดูรายละเอียดเกี่ยวกับ Transition
ได้ที่ updateTransition
สร้างภาพเคลื่อนไหวตามสถานะเป้าหมายด้วย AnimatedContent
AnimatedContent
ที่ประกอบได้จะเคลื่อนไหวเนื้อหาเมื่อมีการเปลี่ยนแปลงตาม
สถานะเป้าหมาย
Row { var count by remember { mutableIntStateOf(0) } Button(onClick = { count++ }) { Text("Add") } AnimatedContent( targetState = count, label = "animated content" ) { targetCount -> // Make sure to use `targetCount`, not `count`. Text(text = "Count: $targetCount") } }
โปรดทราบว่าคุณควรใช้พารามิเตอร์ Lambda และแสดงในเนื้อหาเสมอ API ใช้ค่านี้เป็นคีย์เพื่อระบุเนื้อหาที่ กำลังแสดงอยู่
โดยค่าเริ่มต้น เนื้อหาเริ่มต้นจะค่อยๆ จางหายไป แล้วเนื้อหาเป้าหมายจะค่อยๆ ปรากฏขึ้น
(ลักษณะการทำงานนี้เรียกว่าจางผ่าน) คุณปรับแต่งลักษณะการทำงานของภาพเคลื่อนไหวนี้ได้โดยระบุออบเจ็กต์ ContentTransform
ให้กับพารามิเตอร์ transitionSpec
คุณสร้าง ContentTransform
ได้โดยการรวม
EnterTransition
กับ ExitTransition
โดยใช้ฟังก์ชัน with
แบบ Infix คุณสามารถใช้ SizeTransform
กับ ContentTransform
ได้โดยแนบไว้กับ
ฟังก์ชันแทรก using
AnimatedContent( targetState = count, transitionSpec = { // Compare the incoming number with the previous number. if (targetState > initialState) { // If the target number is larger, it slides up and fades in // while the initial (smaller) number slides up and fades out. slideInVertically { height -> height } + fadeIn() togetherWith slideOutVertically { height -> -height } + fadeOut() } else { // If the target number is smaller, it slides down and fades in // while the initial number slides down and fades out. slideInVertically { height -> -height } + fadeIn() togetherWith slideOutVertically { height -> height } + fadeOut() }.using( // Disable clipping since the faded slide-in/out should // be displayed out of bounds. SizeTransform(clip = false) ) }, label = "animated content" ) { targetCount -> Text(text = "$targetCount") }
EnterTransition
จะกำหนดลักษณะที่เนื้อหาเป้าหมายควรปรากฏ และ
ExitTransition
จะกำหนดลักษณะที่เนื้อหาเริ่มต้นควรหายไป นอกจากฟังก์ชันทั้งหมดของ EnterTransition
และ ExitTransition
ที่พร้อมใช้งานสำหรับ AnimatedVisibility
แล้ว AnimatedContent
ยังมี slideIntoContainer
และ slideOutOfContainer
ด้วย
ซึ่งเป็นทางเลือกที่สะดวกแทน slideInHorizontally/Vertically
และ
slideOutHorizontally/Vertically
ที่คำนวณระยะทางของสไลด์ตาม
ขนาดของเนื้อหาเริ่มต้นและเนื้อหาเป้าหมายของเนื้อหา AnimatedContent
SizeTransform
จะกำหนดวิธีที่
ขนาดควรเคลื่อนไหวระหว่างเนื้อหาเริ่มต้นและเนื้อหาเป้าหมาย คุณมีสิทธิ์เข้าถึงทั้งขนาดเริ่มต้นและขนาดเป้าหมายเมื่อสร้าง
ภาพเคลื่อนไหว SizeTransform
ยังควบคุมว่าจะตัดเนื้อหาให้มีขนาดเท่ากับคอมโพเนนต์ระหว่างภาพเคลื่อนไหวหรือไม่ด้วย
var expanded by remember { mutableStateOf(false) } Surface( color = MaterialTheme.colorScheme.primary, onClick = { expanded = !expanded } ) { AnimatedContent( targetState = expanded, transitionSpec = { fadeIn(animationSpec = tween(150, 150)) togetherWith fadeOut(animationSpec = tween(150)) using SizeTransform { initialSize, targetSize -> if (targetState) { keyframes { // Expand horizontally first. IntSize(targetSize.width, initialSize.height) at 150 durationMillis = 300 } } else { keyframes { // Shrink vertically first. IntSize(initialSize.width, targetSize.height) at 150 durationMillis = 300 } } } }, label = "size transform" ) { targetExpanded -> if (targetExpanded) { Expanded() } else { ContentIcon() } } }
สร้างภาพเคลื่อนไหวให้กับการเปลี่ยนฉากเข้าและออกขององค์ประกอบย่อย
เช่นเดียวกับ AnimatedVisibility
ตัวแก้ไข animateEnterExit
จะอยู่ใน Lambda ของเนื้อหาของ AnimatedContent
ใช้คำสั่งนี้
เพื่อใช้ EnterAnimation
และ ExitAnimation
กับบุตรหลานแต่ละคนทั้งโดยตรงและโดยอ้อม
แยกกัน
เพิ่มภาพเคลื่อนไหวที่กำหนดเอง
ฟิลด์ transition
จะอยู่ใน Lambda เนื้อหาของ AnimatedContent
เช่นเดียวกับ AnimatedVisibility
ใช้เพื่อสร้างเอฟเฟกต์ภาพเคลื่อนไหวที่กำหนดเอง
ซึ่งทำงานพร้อมกับAnimatedContent
การเปลี่ยน ดูรายละเอียดได้ที่
updateTransition
สร้างภาพเคลื่อนไหวระหว่างเลย์เอาต์ 2 แบบด้วย Crossfade
Crossfade
จะเคลื่อนไหวระหว่างเลย์เอาต์ 2 แบบด้วยภาพเคลื่อนไหวแบบครอสเฟด การสลับค่าที่ส่งไปยังพารามิเตอร์ current
จะเปลี่ยนเนื้อหาด้วยภาพเคลื่อนไหวแบบครอสเฟด
var currentPage by remember { mutableStateOf("A") } Crossfade(targetState = currentPage, label = "cross fade") { screen -> when (screen) { "A" -> Text("Page A") "B" -> Text("Page B") } }
ตัวแก้ไขภาพเคลื่อนไหวในตัว
สร้างภาพเคลื่อนไหวการเปลี่ยนแปลงขนาดที่ประกอบได้ด้วย animateContentSize

ตัวแก้ไข animateContentSize
จะสร้างภาพเคลื่อนไหวการเปลี่ยนแปลงขนาด
var expanded by remember { mutableStateOf(false) } Box( modifier = Modifier .background(colorBlue) .animateContentSize() .height(if (expanded) 400.dp else 200.dp) .fillMaxWidth() .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null ) { expanded = !expanded } ) { }
ภาพเคลื่อนไหวของรายการ
หากต้องการทำให้การเรียงลำดับรายการใหม่ภายใน Lazy list หรือกริดเคลื่อนไหว โปรดดูเอกสารประกอบเกี่ยวกับภาพเคลื่อนไหวของรายการเลย์เอาต์แบบ Lazy
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ภาพเคลื่อนไหวตามมูลค่า
- ภาพเคลื่อนไหวใน Compose
- การรองรับเครื่องมือภาพเคลื่อนไหว {:#tooling}