Animation 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
รูปที่ 1 การตั้งค่าอัตราส่วนการหน่วงของสปริงที่แตกต่างกัน
stiffness
กําหนดความเร็วที่สปริงควรเคลื่อนที่ไปยังค่าสุดท้าย ค่าเริ่มต้นคือ Spring.StiffnessMedium
รูปที่ 2 การตั้งค่าความแข็งของสปริงที่แตกต่างกัน
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
กับภาพเคลื่อนไหวต่อไปนี้ที่ขับเคลื่อนโดยสัมผัสของผู้ใช้ เมื่อขัดจังหวะภาพเคลื่อนไหวขณะที่กําลังดำเนินอยู่ คุณจะเห็นได้ว่าการใช้ tween
ตอบสนองไม่ราบรื่นเท่ากับการใช้ spring
รูปที่ 3 การตั้งค่าข้อกำหนด 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 ค่า คุณสามารถระบุ easing เพื่อกำหนดเส้นโค้งการอินเตอร์โพเลชันสำหรับเฟรมหลักแต่ละเฟรมเหล่านี้
คุณระบุค่าที่ 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" )
เล่นภาพเคลื่อนไหวซ้ำด้วย repeatable
repeatable
แสดงภาพเคลื่อนไหวตามระยะเวลา (เช่น tween
หรือ keyframes
) berulang kali จนกว่าจะถึงจำนวนรอบที่ระบุ คุณสามารถส่งพารามิเตอร์ 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
เพื่อปรับเศษส่วนของภาพเคลื่อนไหว ซึ่งจะช่วยให้ค่าที่เคลื่อนไหวสามารถเร่งและช้าลงได้ แทนที่จะเคลื่อนไหวด้วยอัตราคงที่ เศษส่วนคือค่าระหว่าง 0 (เริ่มต้น) ถึง 1.0 (สิ้นสุด) ซึ่งระบุจุดปัจจุบันในภาพเคลื่อนไหว
ความจริงแล้ว Ease คือฟังก์ชันที่ใช้ค่าเศษระหว่าง 0 ถึง 1.0 และแสดงผลเป็นตัวเลขทศนิยม ค่าที่แสดงผลอาจอยู่นอกขอบเขตเพื่อแสดงการเกินหรือต่ำกว่า คุณสร้าง easing ที่กําหนดเองได้ เช่น โค้ดด้านล่าง
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
คอมโพซมีฟังก์ชัน Easing
ในตัวหลายรายการที่ครอบคลุม Use Case ส่วนใหญ่
ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ easing ที่เหมาะสมกับสถานการณ์ของคุณได้ที่ความเร็ว - Material Design
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- ดูเพิ่มเติม
สร้างภาพเคลื่อนไหวของประเภทข้อมูลที่กําหนดเองโดยการแปลงเป็นและจาก AnimationVector
Compose animation API ส่วนใหญ่รองรับ Float
, Color
, Dp
และประเภทข้อมูลพื้นฐานอื่นๆ เป็นค่าภาพเคลื่อนไหวโดยค่าเริ่มต้น แต่บางครั้งคุณอาจต้องสร้างภาพเคลื่อนไหวจากประเภทข้อมูลอื่นๆ รวมถึงประเภทข้อมูลที่กำหนดเอง ในระหว่างที่ภาพเคลื่อนไหว ค่าที่เคลื่อนไหวจะแสดงเป็น AnimationVector
ค่าจะแปลงเป็น AnimationVector
และในทางกลับกันโดย TwoWayConverter
ที่เกี่ยวข้องเพื่อให้ระบบภาพเคลื่อนไหวหลักจัดการค่าเหล่านี้ได้อย่างสอดคล้องกัน เช่น 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
ในตัวบางส่วน
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ภาพเคลื่อนไหวตามมูลค่า
- การพัฒนาโค้ดแบบเป็นขั้นเป็นตอน {:#iterative-code-dev }
- ภาพเคลื่อนไหวใน Compose