API ของภาพเคลื่อนไหวหลายรายการมักยอมรับพารามิเตอร์สำหรับการปรับแต่งลักษณะการทำงาน
ปรับแต่งภาพเคลื่อนไหวด้วยพารามิเตอร์ AnimationSpec
API ภาพเคลื่อนไหวส่วนใหญ่ช่วยให้นักพัฒนาซอฟต์แวร์ปรับแต่งข้อกำหนดภาพเคลื่อนไหวได้โดยใช้พารามิเตอร์ AnimationSpec
ที่ไม่บังคับ
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing), label = "alpha" )
AnimationSpec
มีหลายประเภทสำหรับการสร้างภาพเคลื่อนไหวประเภทต่างๆ
สร้างภาพเคลื่อนไหวตามหลักฟิสิกส์ด้วย spring
spring
สร้างภาพเคลื่อนไหวตามหลักฟิสิกส์ระหว่างค่าเริ่มต้นและค่าสิ้นสุด โดยมีพารามิเตอร์ 2 รายการ ได้แก่ dampingRatio
และ stiffness
dampingRatio
กำหนดว่าสปริงควรจะเด้งมากน้อยเพียงใด ค่าเริ่มต้นคือ
Spring.DampingRatioNoBouncy
stiffness
กำหนดความเร็วที่สปริงควรเคลื่อนที่ไปยังค่าสิ้นสุด ค่าเริ่มต้นคือ Spring.StiffnessMedium
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
spring
จัดการการหยุดชะงักได้ราบรื่นกว่าประเภทที่อิงตามระยะเวลา
AnimationSpec
เนื่องจากรับประกันความต่อเนื่องของความเร็วเมื่อ
ค่าเป้าหมายเปลี่ยนแปลงระหว่างภาพเคลื่อนไหว spring
ใช้เป็น AnimationSpec เริ่มต้นโดย API ภาพเคลื่อนไหวหลายรายการ เช่น animate*AsState
และ
updateTransition
เช่น หากเราใช้spring
config กับภาพเคลื่อนไหวต่อไปนี้ที่
ทำงานเมื่อผู้ใช้แตะ เมื่อขัดจังหวะภาพเคลื่อนไหวขณะที่กำลังทำงาน คุณจะ
เห็นว่าการใช้ tween
ไม่ตอบสนองได้อย่างราบรื่นเท่ากับการใช้ spring
tween
กับ spring
สำหรับภาพเคลื่อนไหวและการขัดจังหวะสร้างภาพเคลื่อนไหวระหว่างค่าเริ่มต้นและค่าสิ้นสุดด้วยเส้นโค้งการค่อยๆ เปลี่ยนโดยใช้ tween
tween
จะเคลื่อนไหวระหว่างค่าเริ่มต้นและค่าสิ้นสุดในช่วงเวลาที่ระบุ
durationMillis
โดยใช้เส้นโค้งการค่อยๆ เปลี่ยน tween
ย่อมาจากคำว่า "ระหว่าง" เนื่องจากค่านี้อยู่ระหว่างค่า 2 ค่า
นอกจากนี้ คุณยังระบุ delayMillis
เพื่อเลื่อนการเริ่มต้นของภาพเคลื่อนไหวได้ด้วย
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
ดูข้อมูลเพิ่มเติมได้ที่การผ่อนปรน
เคลื่อนไหวไปยังค่าที่เฉพาะเจาะจงในเวลาที่กำหนดด้วย keyframes
keyframes
จะเคลื่อนไหวตามค่าสแนปชอตที่ระบุใน
การประทับเวลาต่างๆ ในระยะเวลาของภาพเคลื่อนไหว ระบบจะหาค่าประมาณของค่าภาพเคลื่อนไหวระหว่างค่าคีย์เฟรม 2 ค่าในเวลาใดก็ตาม สำหรับคีย์เฟรมแต่ละรายการเหล่านี้ คุณสามารถระบุการผ่อนแรงเพื่อกำหนดเส้นโค้งการประมาณค่าได้
คุณจะระบุค่าที่ 0 มิลลิวินาทีและที่ระยะเวลาได้หรือไม่ก็ได้ หากคุณไม่ระบุค่าเหล่านี้ ค่าเริ่มต้นจะเป็นค่าเริ่มต้นและค่าสิ้นสุดของ ภาพเคลื่อนไหวตามลำดับ
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 using LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 using FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms }, label = "keyframe" )
สร้างภาพเคลื่อนไหวระหว่างคีย์เฟรมได้อย่างราบรื่นด้วย keyframesWithSplines
หากต้องการสร้างภาพเคลื่อนไหวที่เคลื่อนที่ตามเส้นโค้งที่ราบรื่นขณะเปลี่ยนค่า คุณสามารถใช้ keyframesWithSplines
แทนข้อกำหนดภาพเคลื่อนไหว keyframes
ได้
val offset by animateOffsetAsState( targetValue = Offset(300f, 300f), animationSpec = keyframesWithSpline { durationMillis = 6000 Offset(0f, 0f) at 0 Offset(150f, 200f) atFraction 0.5f Offset(0f, 100f) atFraction 0.7f } )
คีย์เฟรมแบบสไปลน์มีประโยชน์อย่างยิ่งสำหรับการเคลื่อนไหวแบบ 2 มิติของรายการบนหน้าจอ
วิดีโอต่อไปนี้แสดงความแตกต่างระหว่าง keyframes
กับ
keyframesWithSpline
เมื่อกำหนดชุดพิกัด x, y เดียวกันที่วงกลม
ควรทำตาม
keyframes
|
keyframesWithSplines
|
---|---|
ดังที่เห็น คีย์เฟรมแบบสปไลน์ช่วยให้การเปลี่ยนผ่านระหว่างจุดต่างๆ เป็นไปอย่างราบรื่นยิ่งขึ้น เนื่องจากใช้เส้นโค้งเบซิเยร์เพื่อสร้างภาพเคลื่อนไหวระหว่างรายการต่างๆ อย่างราบรื่น ข้อกำหนดนี้ มีประโยชน์สำหรับการเคลื่อนไหวที่กำหนดไว้ล่วงหน้า อย่างไรก็ตาม หากคุณทำงานกับจุดที่ผู้ใช้กำหนดเอง ขอแนะนำให้ใช้สปริงเพื่อให้ได้ความราบรื่นที่คล้ายกันระหว่างจุดต่างๆ เนื่องจากสปริงสามารถหยุดชะงักได้
เล่นภาพเคลื่อนไหวซ้ำด้วย repeatable
repeatable
จะเรียกใช้ภาพเคลื่อนไหวตามระยะเวลา (เช่น tween
หรือ keyframes
)
ซ้ำๆ จนกว่าจะถึงจำนวนการทำซ้ำที่ระบุ คุณสามารถส่งพารามิเตอร์
repeatMode
เพื่อระบุว่าภาพเคลื่อนไหวควรเล่นซ้ำโดย
เริ่มจากต้น (RepeatMode.Restart
) หรือจากท้าย (RepeatMode.Reverse
)
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
เล่นภาพเคลื่อนไหวซ้ำไม่สิ้นสุดด้วย infiniteRepeatable
infiniteRepeatable
คล้ายกับ repeatable
แต่จะทำซ้ำแบบไม่รู้จบ
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
ในการทดสอบที่ใช้
ComposeTestRule
ระบบจะไม่เรียกใช้ภาพเคลื่อนไหวที่ใช้ infiniteRepeatable
คอมโพเนนต์จะแสดงโดยใช้ค่าเริ่มต้นของค่าเคลื่อนไหวแต่ละค่า
สแนปไปยังค่าสิ้นสุดทันทีด้วย snap
snap
เป็น AnimationSpec
พิเศษที่เปลี่ยนค่าเป็นค่าสุดท้ายทันที
คุณระบุ delayMillis
เพื่อเลื่อนเวลาเริ่มต้นของ
ภาพเคลื่อนไหวได้
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
ตั้งค่าฟังก์ชันการลดที่กำหนดเอง
การดำเนินการตามระยะเวลา AnimationSpec
(เช่น tween
หรือ keyframes
) ใช้
Easing
เพื่อปรับเศษส่วนของภาพเคลื่อนไหว ซึ่งช่วยให้ค่าที่เคลื่อนไหว
เร่งและชะลอความเร็วได้ แทนที่จะเคลื่อนไหวด้วยอัตราคงที่ Fraction คือค่าระหว่าง 0 (เริ่มต้น) ถึง 1.0 (สิ้นสุด) ซึ่งระบุจุดปัจจุบันในภาพเคลื่อนไหว
การเปลี่ยนค่าเป็นฟังก์ชันที่รับค่าเศษส่วนระหว่าง 0 ถึง 1.0 และ แสดงผลเป็นค่าลอย ค่าที่แสดงอาจอยู่นอกขอบเขตเพื่อแสดง การยิงเกินหรือยิงไม่ถึง คุณสร้างการลดความเร็วที่กำหนดเองได้เหมือนโค้ดด้านล่าง
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
Compose มีEasing
ฟังก์ชันในตัวหลายอย่างที่ครอบคลุม Use Case ส่วนใหญ่
ดูข้อมูลเพิ่มเติมเกี่ยวกับ Easing ที่ควรใช้ตามสถานการณ์ได้ที่ความเร็ว - Material Design
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- ดูเพิ่มเติม
getInterpolation()
สร้างภาพเคลื่อนไหวให้กับประเภทข้อมูลที่กำหนดเองโดยการแปลงเป็นและจาก AnimationVector
API การเคลื่อนไหวของ Compose ส่วนใหญ่รองรับ Float
, Color
, Dp
และข้อมูลพื้นฐานอื่นๆ
เป็นค่าการเคลื่อนไหวโดยค่าเริ่มต้น แต่บางครั้งคุณอาจต้องเคลื่อนไหว
ข้อมูลประเภทอื่นๆ รวมถึงข้อมูลประเภทที่กำหนดเอง ในระหว่างภาพเคลื่อนไหว ค่าที่เคลื่อนไหวจะแสดงเป็น AnimationVector
TwoWayConverter
ที่เกี่ยวข้องจะแปลงค่าเป็น
AnimationVector
และในทางกลับกัน เพื่อให้
ระบบภาพเคลื่อนไหวหลักจัดการค่าเหล่านี้ได้อย่างสม่ำเสมอ เช่น Int
จะแสดงเป็น AnimationVector1D
ที่มีค่าลอยตัวค่าเดียว
TwoWayConverter
สำหรับ Int
มีลักษณะดังนี้
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color
เป็นชุดค่า 4 ค่า ได้แก่ แดง เขียว น้ำเงิน และอัลฟ่า ดังนั้น
Color
จะแปลงเป็น AnimationVector4D
ที่มีค่าแบบลอย 4 ค่า ด้วยวิธีนี้ ระบบจะแปลงข้อมูลทุกประเภทที่ใช้ในภาพเคลื่อนไหวเป็น AnimationVector1D
, AnimationVector2D
, AnimationVector3D
หรือ AnimationVector4D
โดยขึ้นอยู่กับมิติข้อมูล ซึ่งจะช่วยให้คอมโพเนนต์ต่างๆ ของออบเจ็กต์เคลื่อนไหวแยกกันได้ โดยแต่ละคอมโพเนนต์จะมีการติดตามความเร็วของตัวเอง เข้าถึงตัวแปลงในตัวสำหรับประเภทข้อมูลพื้นฐานได้
โดยใช้ตัวแปลง เช่น Color.VectorConverter
หรือ Dp.VectorConverter
เมื่อต้องการเพิ่มการรองรับประเภทข้อมูลใหม่เป็นค่าภาพเคลื่อนไหว คุณสามารถ
สร้าง TwoWayConverter
ของคุณเองและระบุให้กับ API ตัวอย่างเช่น คุณ
ใช้ animateValueAsState
เพื่อเคลื่อนไหวประเภทข้อมูลที่กำหนดเองได้ดังนี้
data class MySize(val width: Dp, val height: Dp) @Composable fun MyAnimation(targetSize: MySize) { val animSize: MySize by animateValueAsState( targetSize, TwoWayConverter( convertToVector = { size: MySize -> // Extract a float value from each of the `Dp` fields. AnimationVector2D(size.width.value, size.height.value) }, convertFromVector = { vector: AnimationVector2D -> MySize(vector.v1.dp, vector.v2.dp) } ), label = "size" ) }
รายการต่อไปนี้ประกอบด้วย VectorConverter
s ในตัวบางรายการ
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ภาพเคลื่อนไหวตามมูลค่า
- การพัฒนาโค้ดแบบวนซ้ำ {:#iterative-code-dev }
- ภาพเคลื่อนไหวใน Compose