ระบบภาพเคลื่อนไหวของคุณสมบัติเป็นเฟรมเวิร์กที่มีประสิทธิภาพที่ช่วยให้คุณ เพื่อสร้างภาพเคลื่อนไหวได้เกือบทุกอย่าง คุณสามารถกำหนดภาพเคลื่อนไหว เพื่อเปลี่ยนพร็อพเพอร์ตี้ของออบเจ็กต์ เมื่อเวลาผ่านไป ไม่ว่าจะวาดบนหน้าจอหรือไม่ก็ตาม ภาพเคลื่อนไหวของพร็อพเพอร์ตี้จะเปลี่ยนแปลง ค่า (ช่องในออบเจ็กต์) ในช่วงเวลาที่ระบุ หากต้องการให้บางสิ่งเป็นภาพเคลื่อนไหว คุณต้องระบุ คุณสมบัติออบเจ็กต์ที่คุณต้องการทำให้เคลื่อนไหว เช่น ตำแหน่งของวัตถุบนหน้าจอ ระยะเวลา คุณต้องการสร้างภาพเคลื่อนไหว สำหรับค่าใด และค่าที่ต้องการให้เคลื่อนไหว
ระบบภาพเคลื่อนไหวของคุณสมบัติจะให้คุณกำหนดลักษณะเฉพาะต่อไปนี้ของ ภาพเคลื่อนไหว:
- ระยะเวลา: คุณระบุระยะเวลาของภาพเคลื่อนไหวได้ ความยาวเริ่มต้นคือ 300 มิลลิวินาที
- การประมาณค่าเวลา: คุณสามารถระบุวิธีคำนวณค่าสำหรับพร็อพเพอร์ตี้เป็น ของเวลาที่ใช้ไปในปัจจุบันของภาพเคลื่อนไหว
- จำนวนและลักษณะการทำซ้ำ: คุณระบุได้ว่าจะแสดงภาพเคลื่อนไหวซ้ำเมื่อ ถึงช่วงสุดท้ายของระยะเวลาและจำนวนครั้งที่จะแสดงภาพเคลื่อนไหวซ้ำ นอกจากนี้คุณยัง ระบุว่าคุณต้องการให้ภาพเคลื่อนไหวเล่นย้อนกลับหรือไม่ การตั้งค่าเพื่อย้อนการเล่น ภาพเคลื่อนไหวไปข้างหน้าแล้วย้อนกลับมาข้างหลังซ้ำๆ จนกระทั่งถึงจำนวนการทำซ้ำ
- ชุดภาพเคลื่อนไหว: คุณสามารถจัดกลุ่มภาพเคลื่อนไหวเป็นชุดเชิงตรรกะที่เล่นด้วยกัน หรือ เป็นลำดับหรือหลังจากการหน่วงเวลาที่ระบุ
- ความล่าช้าในการรีเฟรชเฟรม: คุณระบุความถี่ในการรีเฟรชเฟรมของภาพเคลื่อนไหวได้ ค่าเริ่มต้นคือรีเฟรชทุก 10 มิลลิวินาที แต่ความเร็วที่แอปพลิเคชันสามารถรีเฟรชเฟรมได้คือ ท้ายที่สุดจะขึ้นอยู่กับความพลุกพล่านของระบบโดยรวม และความรวดเร็วของระบบในการทำงานของตัวจับเวลา
หากต้องการดูตัวอย่างที่สมบูรณ์ของภาพเคลื่อนไหวของพร็อพเพอร์ตี้ โปรดดู
คลาส ChangeColor
ใน CustomTransition
ตัวอย่างใน GitHub
วิธีการทำงานของภาพเคลื่อนไหวของพร็อพเพอร์ตี้
ก่อนอื่น มาดูวิธีการทำงานของภาพเคลื่อนไหวโดยใช้ตัวอย่างง่ายๆ กัน รูปที่ 1 แสดง
วัตถุสมมติที่เคลื่อนไหวได้โดยมีพร็อพเพอร์ตี้ x
ซึ่งแสดง
ตำแหน่งแนวนอนบนหน้าจอ ระยะเวลาของภาพเคลื่อนไหวกำหนดไว้ที่ 40 มิลลิวินาที และระยะทาง
ในการเดินทาง 40 พิกเซล ทุก 10 มิลลิวินาทีซึ่งเป็นอัตราการรีเฟรชเฟรมเริ่มต้น วัตถุจะเคลื่อนไหว
แนวนอน 10 พิกเซล เมื่อครบ 40 มิลลิวินาที ภาพเคลื่อนไหวจะหยุดและวัตถุจะสิ้นสุดในเวลา
แนวนอนที่ 40 นี่คือตัวอย่างของภาพเคลื่อนไหวที่มีการประมาณค่าในช่วงเชิงเส้น
วัตถุเคลื่อนที่ด้วยความเร็วคงที่
![](https://developer.android.com/static/images/animation/animation-linear.png?authuser=19&hl=th)
รูปที่ 1 ตัวอย่างภาพเคลื่อนไหวเชิงเส้น
นอกจากนี้ คุณยังระบุให้ภาพเคลื่อนไหวมีการประมาณค่าในช่วงที่ไม่ใช่แบบเชิงเส้นได้ด้วย รูปที่ 2 แสดง วัตถุสมมุติที่จะเร่งความเร็วในช่วงเริ่มต้นของภาพเคลื่อนไหวและลดลงในช่วง สิ้นสุดภาพเคลื่อนไหว วัตถุยังคงเคลื่อนที่ 40 พิกเซลใน 40 มิลลิวินาที แต่ไม่เป็นเชิงเส้น ใน ภาพเคลื่อนไหวนี้จะเร่งความเร็วถึงจุดกึ่งกลาง จากนั้นจะค่อยๆ ลดลงจาก จุดกึ่งกลางไปจนถึงจุดสิ้นสุดของภาพเคลื่อนไหว ดังที่แสดงในรูปที่ 2 ระยะทางที่เดินทาง ที่จุดเริ่มต้นและจุดสิ้นสุดของภาพเคลื่อนไหวน้อยกว่าช่วงกลาง
![](https://developer.android.com/static/images/animation/animation-nonlinear.png?authuser=19&hl=th)
รูปที่ 2 ตัวอย่างภาพเคลื่อนไหวแบบไม่เชิงเส้น
มาดูรายละเอียดกันว่าองค์ประกอบสำคัญของระบบภาพเคลื่อนไหวของพร็อพเพอร์ตี้ จะคำนวณภาพเคลื่อนไหวแบบเดียวกับที่แสดงด้านบน รูปที่ 3 แสดงให้เห็นว่าคลาสหลักๆ ที่ทำงานร่วมกัน
![](https://developer.android.com/static/images/animation/valueanimator.png?authuser=19&hl=th)
รูปที่ 3 วิธีคำนวณภาพเคลื่อนไหว
ออบเจ็กต์ ValueAnimator
จะติดตามเวลาของภาพเคลื่อนไหว
เช่น ระยะเวลาที่ภาพเคลื่อนไหวทำงาน และค่าปัจจุบันของคุณสมบัติที่แสดง
เป็นภาพเคลื่อนไหว
ValueAnimator
จะสรุป TimeInterpolator
ซึ่งกำหนดการประมาณค่าในช่วงของภาพเคลื่อนไหว และ TypeEvaluator
ซึ่งจะกําหนดวิธีการคํานวณค่าของพร็อพเพอร์ตี้
ภาพเคลื่อนไหว ตัวอย่างเช่น ในรูปที่ 2 TimeInterpolator
ที่ใช้จะเป็น
AccelerateDecelerateInterpolator
และ TypeEvaluator
จะเป็น IntEvaluator
หากต้องการเริ่มภาพเคลื่อนไหว ให้สร้าง ValueAnimator
และกำหนด
ค่าเริ่มต้นและสิ้นสุดสำหรับพร็อพเพอร์ตี้ที่คุณต้องการให้เคลื่อนไหว พร้อมด้วยระยะเวลาของ
ภาพเคลื่อนไหว เมื่อคุณเรียก start()
ภาพเคลื่อนไหว
เริ่มต้นขึ้น ระหว่างภาพเคลื่อนไหวทั้งหมด ValueAnimator
จะคำนวณเศษส่วนที่ผ่านไป
ระหว่าง 0 ถึง 1 ซึ่งขึ้นอยู่กับระยะเวลาของภาพเคลื่อนไหวและเวลาที่ผ่านไป
เศษส่วนที่ผ่านไปหมายถึงเปอร์เซ็นต์ของเวลาที่ภาพเคลื่อนไหวเสร็จสมบูรณ์ ซึ่ง 0 หมายถึง 0%
และ 1 หมายถึง 100% ตัวอย่างเช่น ในรูปที่ 1 ส่วนที่ผ่านไปเมื่อ t = 10 มิลลิวินาทีจะเป็น .25
เนื่องจากระยะเวลารวมคือ t = 40 มิลลิวินาที
เมื่อ ValueAnimator
คำนวณเศษส่วนที่ผ่านไปเสร็จแล้ว
จะเรียก TimeInterpolator
ที่ตั้งไว้ในปัจจุบันเพื่อคำนวณ
เศษส่วนที่ประมาณ เศษส่วนที่ประมาณจะแมปเศษส่วนที่ผ่านไปยังเศษส่วนใหม่
เศษส่วนที่คำนึงถึงการประมาณค่าในช่วงที่ตั้งค่าไว้ ตัวอย่างเช่น ในรูปที่ 2
เนื่องจากภาพเคลื่อนไหวจะเร่งความเร็วขึ้นช้าๆ เศษส่วนที่ประมาณหรือ 0 .15 จะน้อยกว่า
เศษส่วนที่ผ่านไป, .25, ที่ t = 10 มิลลิวินาที ในรูปที่ 1 เศษส่วนที่ประมาณจะเท่ากับ
ส่วนที่ผ่านไป
เมื่อคำนวณเศษส่วนที่ประมาณแล้ว จะเรียก ValueAnimator
ครั้ง
TypeEvaluator
ที่เหมาะสมเพื่อคำนวณค่าของ
พร็อพเพอร์ตี้ที่คุณกำลังสร้างภาพเคลื่อนไหวโดยอิงจากส่วนที่ประมาณค่า ค่าเริ่มต้น และตัวแปร
ค่าสิ้นสุดของภาพเคลื่อนไหว ตัวอย่างเช่น ในรูปที่ 2 เศษส่วนที่ประมาณคือ 0 .15 เมื่อ t =
10 มิลลิวินาที ดังนั้นค่าสำหรับพร็อพเพอร์ตี้ในขณะนั้นจะเป็น .15 × (40 - 0) หรือ 6
ความแตกต่างระหว่างภาพเคลื่อนไหวของพร็อพเพอร์ตี้กับภาพเคลื่อนไหวในมุมมอง
ระบบการดูภาพเคลื่อนไหวจะทำให้สามารถเคลื่อนไหวได้เฉพาะ View
เท่านั้น
ดังนั้นหากต้องการทำให้ออบเจ็กต์ที่ไม่ใช่ View
เคลื่อนไหว
คุณจะต้องใช้
โค้ดของคุณเองได้ ระบบการดูภาพเคลื่อนไหวยังถูกจำกัด จากข้อเท็จจริงที่ว่า
ทำให้วัตถุ View
เคลื่อนไหวได้บางส่วน เช่น การปรับขนาดและ
เช่น การหมุนมุมมอง แต่ไม่ใช่สีพื้นหลัง
ข้อเสียอีกอย่างของระบบภาพเคลื่อนไหวในการดูคือระบบจะแก้ไขเฉพาะจุดที่ มีการวาดมุมมอง ไม่ใช่ตัวมุมมองจริง เช่น หากทำให้ปุ่มเคลื่อนไหว บนหน้าจอ ปุ่มจะวาดได้อย่างถูกต้อง แต่ตำแหน่งจริงที่คุณคลิก ปุ่มไม่เปลี่ยนแปลง คุณจึงต้องใช้ตรรกะของคุณเองเพื่อจัดการกับเรื่องนี้
ด้วยระบบการเคลื่อนไหวของคุณสมบัติ ข้อจำกัดเหล่านี้จะถูกนำออกไปทั้งหมด และคุณสามารถสร้างภาพเคลื่อนไหว พร็อพเพอร์ตี้ใดๆ ของออบเจ็กต์ใดๆ (ข้อมูลพร็อพเพอร์ตี้และไม่ใช่มุมมอง) และตัวออบเจ็กต์จะถูกแก้ไข ระบบการเคลื่อนไหวของพร็อพเพอร์ตี้ยังมีประสิทธิภาพมากขึ้นในการสร้างภาพเคลื่อนไหว ที่ ในระดับสูง คุณจะกำหนดผู้สร้างภาพเคลื่อนไหวให้กับคุณสมบัติที่ต้องการให้เคลื่อนไหว เช่น สี ตำแหน่ง หรือขนาด และสามารถกำหนดลักษณะต่างๆ ของภาพเคลื่อนไหว เช่น การประมาณค่าในช่วงและ การซิงค์ของผู้สร้างภาพเคลื่อนไหวหลายๆ ตัว
อย่างไรก็ตาม ระบบภาพเคลื่อนไหวนี้จะใช้เวลาตั้งค่าน้อยกว่าและใช้เวลาเขียนโค้ดน้อยกว่า ภาพเคลื่อนไหวในมุมมองสามารถทำสิ่งต่างๆ ทั้งหมดที่คุณจำเป็นต้องทำ หรือถ้าโค้ดที่คุณมีอยู่แล้ว ทำงานได้ตามที่ต้องการ ไม่จำเป็นต้องใช้ระบบภาพเคลื่อนไหวของคุณสมบัติ นอกจากนี้ยังอาจ การใช้ภาพเคลื่อนไหวทั้ง 2 ระบบในสถานการณ์ที่ต่างกันหากต้องมีกรณีการใช้งานเกิดขึ้น
ภาพรวม API
คุณสามารถค้นหา API ส่วนใหญ่ของระบบภาพเคลื่อนไหวของพร็อพเพอร์ตี้ได้ใน android.animation
เนื่องจากระบบการดูภาพเคลื่อนไหวอยู่แล้ว
จะกำหนดตัวประมาณค่ากลางหลายรายการใน android.view.animation
คุณสามารถใช้
ตัวกำหนดช่วงต่างๆ ในระบบภาพเคลื่อนไหวของที่พักด้วย ตารางต่อไปนี้อธิบายถึง
ของระบบภาพเคลื่อนไหวคุณสมบัติ
คลาส Animator
มีโครงสร้างพื้นฐานสำหรับการสร้าง
ภาพเคลื่อนไหว ปกติแล้วคุณไม่ได้ใช้คลาสนี้โดยตรงเนื่องจากมีเพียง
ฟังก์ชันการทํางานที่ต้องขยายเพื่อรองรับค่าภาพเคลื่อนไหวอย่างเต็มรูปแบบ ดังต่อไปนี้
คลาสย่อยจะขยาย Animator
:
ตาราง 1 แอนิเมเตอร์
ชั้น | คำอธิบาย |
---|---|
ValueAnimator |
เครื่องมือกำหนดเวลาหลักสำหรับการเคลื่อนไหวของพร็อพเพอร์ตี้ที่คำนวณค่าสำหรับ
ที่จะเป็นภาพเคลื่อนไหว ซึ่งมีฟังก์ชันหลักทั้งหมดที่คํานวณภาพเคลื่อนไหว
และมีรายละเอียดช่วงเวลาของภาพเคลื่อนไหวแต่ละภาพ มีข้อมูลว่า
ภาพเคลื่อนไหวซ้ำ ผู้ฟังที่ได้รับเหตุการณ์อัปเดต และความสามารถในการตั้งค่าแบบกำหนดเอง
ประเภทต่างๆ ที่จะประเมิน คุณสมบัติในการสร้างภาพเคลื่อนไหวมีอยู่ด้วยกัน 2 ส่วน ได้แก่ การคำนวณหาค่าที่เคลื่อนไหวได้
ค่า แล้วตั้งค่าเหล่านั้นในออบเจ็กต์และคุณสมบัติที่กำลังเป็นภาพเคลื่อนไหว ValueAnimator ไม่ได้รับผลงานชิ้นที่ 2 คุณจึงต้องฟัง
สําหรับการอัปเดตค่าที่คำนวณโดย ValueAnimator และ
แก้ไขวัตถุที่คุณต้องการให้เคลื่อนไหวด้วยตรรกะของคุณเอง ดูหัวข้อเกี่ยวกับ
ภาพเคลื่อนไหวด้วย ValueAnimator สำหรับข้อมูลเพิ่มเติม |
ObjectAnimator |
คลาสย่อยของ ValueAnimator ที่ช่วยให้คุณกำหนดเป้าหมายได้
และพร็อพเพอร์ตี้ของออบเจ็กต์
เพื่อให้เคลื่อนไหวได้ คลาสนี้จะอัปเดตพร็อพเพอร์ตี้ตามนั้นเมื่อ
โมเดลจะคำนวณค่าใหม่สำหรับภาพเคลื่อนไหว คุณต้องการใช้
เป็นส่วนใหญ่ ObjectAnimator
เพราะจะทำให้กระบวนการสร้างภาพเคลื่อนไหวของค่าในออบเจ็กต์เป้าหมายง่ายขึ้นมาก อย่างไรก็ตาม
บางครั้งคุณต้องการใช้ ValueAnimator โดยตรงเนื่องจาก ObjectAnimator มีข้อจำกัดเพิ่มเติมเล็กน้อย เช่น ต้องใช้
เมธอดของตัวเข้าถึงที่จะมีอยู่ในออบเจ็กต์เป้าหมาย |
AnimatorSet |
มีกลไกในการจัดกลุ่มภาพเคลื่อนไหวเข้าด้วยกันเพื่อให้เล่นได้ ที่เกี่ยวข้องกัน คุณสามารถตั้งค่าภาพเคลื่อนไหวให้เล่นด้วยกัน เล่นเป็นลำดับ หรือตามหลัง การหน่วงเวลาที่ระบุ ดูส่วนเกี่ยวกับการออกแบบท่าเต้นหลายตัว ภาพเคลื่อนไหวด้วยชุดภาพเคลื่อนไหวเพื่อดูข้อมูลเพิ่มเติม |
ผู้ประเมินจะบอกระบบการเคลื่อนไหวของพร็อพเพอร์ตี้ว่าจะคํานวณค่าสำหรับ
โดยใช้ข้อมูลการจับเวลาที่ได้จาก Animator
ค่าเริ่มต้นและสิ้นสุดของภาพเคลื่อนไหว และคำนวณค่าที่เคลื่อนไหวของคุณสมบัติ
อิงตามข้อมูลนี้ ระบบภาพเคลื่อนไหวของที่พักมีผู้ประเมินดังต่อไปนี้
ตาราง 2 ผู้ประเมิน
คลาส/อินเทอร์เฟซ | คำอธิบาย |
---|---|
IntEvaluator |
ผู้ประเมินเริ่มต้นที่คำนวณค่าสำหรับที่พัก int รายการ |
FloatEvaluator |
ผู้ประเมินเริ่มต้นที่คำนวณค่าสำหรับที่พัก float รายการ |
ArgbEvaluator |
ตัวประเมินเริ่มต้นในการคำนวณค่าสำหรับคุณสมบัติของสีที่แสดง เป็นค่าฐานสิบหก |
TypeEvaluator |
อินเทอร์เฟซที่ให้คุณสร้างผู้ประเมินของตัวเอง ถ้ากำลังทำให้เคลื่อนไหว
พร็อพเพอร์ตี้ของออบเจ็กต์ที่ไม่ใช่ int , float หรือสี
คุณต้องใช้อินเทอร์เฟซ TypeEvaluator เพื่อระบุวิธี
เพื่อคำนวณค่าภาพเคลื่อนไหวของคุณสมบัติออบเจ็กต์ คุณยังระบุ TypeEvaluator ที่กำหนดเองสำหรับ int , float และสีได้ด้วย
หากต้องการประมวลผลประเภทเหล่านั้นให้แตกต่างจากลักษณะการทำงานเริ่มต้น
ดูส่วนเกี่ยวกับการใช้ TypeEvaluator สำหรับเพิ่มเติม
เกี่ยวกับวิธีเขียนผู้ประเมินที่กำหนดเอง |
ตัวกำหนดเวลาจะกำหนดวิธีการคำนวณค่าเฉพาะในภาพเคลื่อนไหว
ของเวลา เช่น คุณสามารถระบุภาพเคลื่อนไหวให้เกิดขึ้นในเชิงเส้นตลอดทั้งรายการ
ภาพเคลื่อนไหว ซึ่งหมายความว่าภาพเคลื่อนไหวจะเคลื่อนที่อย่างเท่าๆ กันตลอดระยะเวลา หรือคุณระบุภาพเคลื่อนไหว
เพื่อใช้เวลาที่ไม่ใช่เชิงเส้น ตัวอย่างเช่น เร่งความเร็วในตอนเริ่มต้นและลดความเร็วลงในช่วง
สิ้นสุดภาพเคลื่อนไหว ตารางที่ 3 จะอธิบายตัวประมาณค่ากลางที่อยู่ใน android.view.animation
หากไม่มีเครื่องมืออินเตอร์โพลเตอร์ใดๆ ที่มีให้เหมาะสม
ตามความต้องการ ติดตั้งอินเทอร์เฟซ TimeInterpolator
และสร้างอินเทอร์เฟซของคุณเอง ดูการใช้ตัวแทรกกลางสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีเขียน
ตัวกำหนดช่วง
ตารางที่ 3 อินเตอร์โพเลเตอร์
คลาส/อินเทอร์เฟซ | คำอธิบาย |
---|---|
AccelerateDecelerateInterpolator |
ตัวกำหนดอัตราการเปลี่ยนแปลงที่มีอัตราการเปลี่ยนแปลงเริ่มต้นและสิ้นสุดอย่างช้าๆ แต่เพิ่มขึ้นอย่างรวดเร็ว ผ่านตรงกลาง |
AccelerateInterpolator |
ตัวการประมาณค่าที่มีอัตราการเปลี่ยนแปลงจะเริ่มอย่างช้าๆ จากนั้น เร็วขึ้น |
AnticipateInterpolator |
ตัวกำหนดการเปลี่ยนแปลงที่การเปลี่ยนแปลงเริ่มต้นแบบถอยหลังแล้วเลื่อนไปข้างหน้า |
AnticipateOvershootInterpolator |
ตัวกำหนดการเปลี่ยนแปลงที่การเปลี่ยนแปลงเริ่มขึ้นแบบถอยหลัง ปัดไปข้างหน้าและข้ามผ่าน ค่าเป้าหมาย แล้วกลับไปที่ค่าสุดท้าย |
BounceInterpolator |
ตัวกำหนดการเปลี่ยนแปลงที่การเปลี่ยนแปลงจะตีกลับในช่วงท้าย |
CycleInterpolator |
ตัวกำหนดที่มีภาพเคลื่อนไหวเล่นซ้ำตามจำนวนรอบที่ระบุ |
DecelerateInterpolator |
ตัวกำหนดอัตราการเปลี่ยนแปลงที่อัตราการเปลี่ยนแปลงจะเริ่มต้นอย่างรวดเร็ว จากนั้น ช้าลง |
LinearInterpolator |
ตัวกำหนดอัตราการเปลี่ยนแปลงที่มีอัตราการเปลี่ยนแปลงคงที่ |
OvershootInterpolator |
ตัวกำหนดการเปลี่ยนแปลงที่มีการเปลี่ยนแปลงไปข้างหน้าและเกินค่าสุดท้ายในตอนนั้น กลับมา |
TimeInterpolator |
อินเทอร์เฟซที่ให้คุณติดตั้งอินเตอร์โพลเตอร์ของคุณเอง |
สร้างภาพเคลื่อนไหวโดยใช้ ValueAnimator
คลาส ValueAnimator
จะช่วยให้คุณทำให้ค่าบางประเภทเคลื่อนไหวสำหรับค่า
ระยะเวลาของภาพเคลื่อนไหวด้วยการระบุชุด int
, float
หรือสี
มูลค่าที่เคลื่อนไหวได้ คุณจะได้รับ ValueAnimator
เมื่อโทรหา 1
เมธอดจากโรงงาน: ofInt()
, ofFloat()
หรือ ofObject()
เช่น
Kotlin
ValueAnimator.ofFloat(0f, 100f).apply { duration = 1000 start() }
Java
ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f); animation.setDuration(1000); animation.start();
ในโค้ดนี้ ValueAnimator
จะเริ่มคำนวณค่าของฟิลด์
ระหว่าง 0 ถึง 100 เป็นระยะเวลา 1,000 มิลลิวินาที เมื่อเมธอด start()
ทำงาน
นอกจากนี้คุณยังระบุประเภทที่กำหนดเองเพื่อให้เคลื่อนไหวได้ด้วยการทำสิ่งต่อไปนี้
Kotlin
ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply { duration = 1000 start() }
Java
ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue); animation.setDuration(1000); animation.start();
ในโค้ดนี้ ValueAnimator
จะเริ่มคำนวณค่าของฟิลด์
ภาพเคลื่อนไหวตั้งแต่ startPropertyValue
ถึง endPropertyValue
โดยใช้
ตรรกะที่กำหนดโดย MyTypeEvaluator
เป็นระยะเวลา 1, 000 มิลลิวินาที เมื่อเมธอด start()
ทำงาน
คุณสามารถใช้ค่าของภาพเคลื่อนไหวโดยเพิ่ม
AnimatorUpdateListener
ลงในออบเจ็กต์ ValueAnimator
ดังที่แสดงใน
รหัสต่อไปนี้:
Kotlin
ValueAnimator.ofObject(...).apply { ... addUpdateListener { updatedAnimation -> // You can use the animated value in a property that uses the // same type as the animation. In this case, you can use the // float value in the translationX property. textView.translationX = updatedAnimation.animatedValue as Float } ... }
Java
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator updatedAnimation) { // You can use the animated value in a property that uses the // same type as the animation. In this case, you can use the // float value in the translationX property. float animatedValue = (float)updatedAnimation.getAnimatedValue(); textView.setTranslationX(animatedValue); } });
ในonAnimationUpdate()
คุณจะสามารถเข้าถึงค่าของภาพเคลื่อนไหวที่อัปเดตแล้ว และนำไปใช้ในพร็อพเพอร์ตี้
มุมมองของคุณ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Listener โปรดดูส่วนเกี่ยวกับ
Listener ภาพเคลื่อนไหว
สร้างภาพเคลื่อนไหวโดยใช้ ObjectAnimator
ObjectAnimator
เป็นคลาสย่อยของ ValueAnimator
(กล่าวถึงในส่วนก่อนหน้านี้) และรวมเวลาเข้าด้วยกัน
การคำนวณเครื่องมือและค่าของ ValueAnimator
ที่มีความสามารถในการ
ทำให้พร็อพเพอร์ตี้ที่มีชื่อของออบเจ็กต์เป้าหมายเคลื่อนไหว ซึ่งจะทำให้วัตถุต่างๆ เคลื่อนไหวได้ง่ายขึ้น
ไม่จำเป็นต้องใช้ ValueAnimator.AnimatorUpdateListener
อีกต่อไป
เพราะคุณสมบัติเคลื่อนไหวจะอัปเดตโดยอัตโนมัติ
การสร้างตัวอย่าง ObjectAnimator
นั้นคล้ายกับ ValueAnimator
แต่คุณยังระบุออบเจ็กต์และชื่อของพร็อพเพอร์ตี้ของออบเจ็กต์นั้นด้วย (เป็น
สตริง) พร้อมกับค่าที่จะเคลื่อนไหวระหว่างรายการต่อไปนี้
Kotlin
ObjectAnimator.ofFloat(textView, "translationX", 100f).apply { duration = 1000 start() }
Java
ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f); animation.setDuration(1000); animation.start();
หากต้องการให้มีพร็อพเพอร์ตี้การอัปเดต ObjectAnimator
อย่างถูกต้อง คุณจะต้องทำดังนี้
- พร็อพเพอร์ตี้ออบเจ็กต์ที่คุณกำลังทำให้เคลื่อนไหวต้องมีฟังก์ชันตัวตั้งค่า (ในกรณีอูฐ) ในรูปแบบ
set<PropertyName>()
เนื่องจากObjectAnimator
อัปเดตพร็อพเพอร์ตี้โดยอัตโนมัติระหว่างที่มีภาพเคลื่อนไหว พร็อพเพอร์ตี้ต้องเข้าถึงพร็อพเพอร์ตี้ได้ ด้วยเมธอด Setter นี้ ตัวอย่างเช่น หากชื่อพร็อพเพอร์ตี้คือfoo
คุณจะต้อง มีเมธอดsetFoo()
ถ้าไม่มีเมธอด Setter นี้อยู่ คุณมี ตัวเลือก:- เพิ่มเมธอดตัวตั้งค่าลงในชั้นเรียนหากคุณมีสิทธิ์
- ใช้คลาส Wrapper ที่คุณมีสิทธิ์เปลี่ยนแปลงและให้ Wrapper นั้นได้รับ ด้วยเมธอด setter ที่ถูกต้อง และส่งต่อไปยังออบเจ็กต์ต้นฉบับ
- โปรดใช้
ValueAnimator
แทน
- หากคุณระบุเพียงค่าเดียวสำหรับพารามิเตอร์
values...
ในเมธอดเริ่มต้นObjectAnimator
ค่าใดค่าหนึ่ง ระบบจะถือว่าเป็นค่าสิ้นสุดของพารามิเตอร์ ภาพเคลื่อนไหว ดังนั้น พร็อพเพอร์ตี้ออบเจ็กต์ที่คุณกำลังสร้างการเคลื่อนไหวต้องมีฟังก์ชัน Getter ที่ใช้เพื่อรับค่าเริ่มต้นของภาพเคลื่อนไหว ฟังก์ชัน Getter ต้องอยู่ในฟิลด์ ของget<PropertyName>()
ตัวอย่างเช่น หากชื่อพร็อพเพอร์ตี้คือfoo
คุณต้องมีเมธอดgetFoo()
- เมธอด Getter (หากจำเป็น) และ Setter ของพร็อพเพอร์ตี้ที่คุณทำให้เคลื่อนไหวต้อง
ดำเนินการในประเภทเดียวกับค่าเริ่มต้นและสิ้นสุดที่คุณระบุเป็น
ObjectAnimator
ตัวอย่างเช่น คุณต้องมีtargetObject.setPropName(float)
และtargetObject.getPropName()
หากคุณสร้างObjectAnimator
ต่อไปนี้ObjectAnimator.ofFloat(targetObject, "propName", 1f)
- คุณอาจจำเป็นต้องเรียกใช้เมธอด
invalidate()
ในมุมมองเพื่อบังคับให้หน้าจอวาดใหม่ด้วยเมธอด อัปเดตค่าภาพเคลื่อนไหวแล้ว โดยดำเนินการในonAnimationUpdate()
Callback เช่น การทำให้คุณสมบัติสีของวัตถุที่วาดได้เคลื่อนไหวมีเพียงแค่การอัปเดต เมื่อวัตถุนั้นวาดใหม่เอง ตัวตั้งค่าพร็อพเพอร์ตี้ทั้งหมดในข้อมูลพร็อพเพอร์ตี้ เช่นsetAlpha()
และsetTranslationX()
ทำให้มุมมองเป็นโมฆะ ดังนั้นคุณจึงไม่จำเป็นต้องทำให้มุมมองเป็นโมฆะเมื่อเรียกใช้ ด้วยค่าใหม่ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Listener โปรดดูส่วนเกี่ยวกับ Listener ภาพเคลื่อนไหว
ออกแบบภาพเคลื่อนไหวหลายภาพโดยใช้ AnimatorSet
ในหลายกรณี คุณต้องการเล่นภาพเคลื่อนไหวที่ขึ้นอยู่กับเวลาที่ภาพเคลื่อนไหวอีกภาพหนึ่งเริ่มเล่นหรือ
เสร็จสิ้น ระบบ Android ให้คุณรวมภาพเคลื่อนไหวเข้าด้วยกันเป็น AnimatorSet
เพื่อให้คุณระบุได้ว่าจะเริ่มสร้างภาพเคลื่อนไหวหรือไม่
พร้อมกัน ตามลำดับ หรือหลังจากการหน่วงเวลาที่ระบุ และยังฝังออบเจ็กต์ AnimatorSet
รายการไว้ภายในกันและกันได้ด้วย
ข้อมูลโค้ดต่อไปนี้เล่น Animator
ต่อไปนี้
ออบเจ็กต์ในลักษณะต่อไปนี้
- เล่น
bounceAnim
- เล่น
squashAnim1
,squashAnim2
,stretchAnim1
และstretchAnim2
ในเวลาเดียวกัน - เล่น
bounceBackAnim
- เล่น
fadeAnim
Kotlin
val bouncer = AnimatorSet().apply { play(bounceAnim).before(squashAnim1) play(squashAnim1).with(squashAnim2) play(squashAnim1).with(stretchAnim1) play(squashAnim1).with(stretchAnim2) play(bounceBackAnim).after(stretchAnim2) } val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply { duration = 250 } AnimatorSet().apply { play(bouncer).before(fadeAnim) start() }
Java
AnimatorSet bouncer = new AnimatorSet(); bouncer.play(bounceAnim).before(squashAnim1); bouncer.play(squashAnim1).with(squashAnim2); bouncer.play(squashAnim1).with(stretchAnim1); bouncer.play(squashAnim1).with(stretchAnim2); bouncer.play(bounceBackAnim).after(stretchAnim2); ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(bouncer).before(fadeAnim); animatorSet.start();
Listener ภาพเคลื่อนไหว
คุณฟังเหตุการณ์สำคัญระหว่างระยะเวลาของภาพเคลื่อนไหวกับผู้ฟังที่อธิบายไว้ด้านล่างได้
Animator.AnimatorListener
onAnimationStart()
- เรียกใช้เมื่อภาพเคลื่อนไหวเริ่มonAnimationEnd()
- เรียกใช้เมื่อภาพเคลื่อนไหวสิ้นสุดonAnimationRepeat()
- เรียกใช้เมื่อภาพเคลื่อนไหวเล่นซ้ำonAnimationCancel()
- เรียกใช้เมื่อมีการยกเลิกภาพเคลื่อนไหว ภาพเคลื่อนไหวที่ยกเลิก โทรหาonAnimationEnd()
ด้วย ไม่ว่าจะสิ้นสุดลงด้วยวิธีใดก็ตาม
ValueAnimator.AnimatorUpdateListener
-
onAnimationUpdate()
- เรียกใช้ภาพเคลื่อนไหวทุกเฟรม ฟังกิจกรรมนี้เพื่อ ใช้ค่าที่คำนวณแล้วซึ่งสร้างโดยValueAnimator
ระหว่าง ภาพเคลื่อนไหว หากต้องการใช้ค่า ให้ค้นหาออบเจ็กต์ValueAnimator
ผ่านไปยังเหตุการณ์เพื่อรับค่าภาพเคลื่อนไหวปัจจุบันด้วยเมธอดgetAnimatedValue()
การนำไปใช้งาน Listener เป็นสิ่งที่จำเป็นหากคุณใช้ValueAnimator
คุณอาจต้องเรียกใช้ ขึ้นอยู่กับพร็อพเพอร์ตี้หรือออบเจ็กต์ที่กำลังทำให้เคลื่อนไหว
invalidate()
ในมุมมองเพื่อบังคับให้พื้นที่ดังกล่าวของ เพื่อแสดงค่าภาพเคลื่อนไหวใหม่ ตัวอย่างเช่น การทำให้ คุณสมบัติสีของวัตถุที่ถอนได้ทำให้มีการอัปเดตหน้าจอเฉพาะเมื่อวัตถุนั้น วาดตัวเองอีกครั้ง ผู้ตั้งค่าพร็อพเพอร์ตี้ทั้งหมดใน View เช่นsetAlpha()
และsetTranslationX()
ทำให้มุมมองไม่ถูกต้อง อย่างเหมาะสม เพื่อให้คุณไม่ต้องทำให้มุมมองไม่ถูกต้องเมื่อเรียกใช้เมธอดเหล่านี้ด้วยค่าใหม่
-
คุณสามารถขยายคลาส AnimatorListenerAdapter
แทน
จะใช้อินเทอร์เฟซ Animator.AnimatorListener
หากคุณไม่ได้
ต้องการใช้ทุกเมธอดของ Animator.AnimatorListener
ของ Google ชั้นเรียน AnimatorListenerAdapter
ให้ค่าว่าง
ของวิธีการที่คุณสามารถเลือกลบล้างได้
ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้สร้าง AnimatorListenerAdapter
สำหรับเฉพาะ onAnimationEnd()
ติดต่อกลับ:
Kotlin
ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply { duration = 250 addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { balls.remove((animation as ObjectAnimator).target) } }) }
Java
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); fadeAnim.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { balls.remove(((ObjectAnimator)animation).getTarget()); }
สร้างภาพเคลื่อนไหวการเปลี่ยนเลย์เอาต์ของออบเจ็กต์ ViewGroup
ระบบภาพเคลื่อนไหวของคุณสมบัติสร้างภาพเคลื่อนไหวให้กับการเปลี่ยนแปลงของออบเจ็กต์ ViewGroup ตลอดจนช่วยให้วัตถุ View เคลื่อนไหวได้ง่าย
คุณสามารถทำให้การเปลี่ยนแปลงเลย์เอาต์ภายใน ViewGroup เป็นภาพเคลื่อนไหวได้โดยใช้
LayoutTransition
ชั้นเรียน มุมมองภายใน ViewGroup สามารถ
เมื่อมีภาพเคลื่อนไหวที่ปรากฏขึ้นและหายไป
เมื่อคุณเพิ่มรายการเหล่านั้นลงใน
ให้นำออกจาก ViewGroup หรือเมื่อคุณเรียกใช้
setVisibility()
วิธีที่มี
VISIBLE
, INVISIBLE
หรือ
GONE
มุมมองที่เหลือใน ViewGroup ยังสามารถ
ภาพเคลื่อนไหวไปยังตำแหน่งใหม่เมื่อคุณเพิ่มหรือนำมุมมองออก คุณสามารถกำหนด
ภาพเคลื่อนไหวต่อไปนี้ในออบเจ็กต์ LayoutTransition
โดยโทรไปที่ setAnimator()
และการส่งผ่านในออบเจ็กต์ Animator
ที่มีหนึ่งในออบเจ็กต์
ค่าคงที่ LayoutTransition
ต่อไปนี้
APPEARING
- ธงที่ระบุภาพเคลื่อนไหวที่ทำงานบนรายการที่ ที่ปรากฏในคอนเทนเนอร์CHANGE_APPEARING
- ธงที่ระบุภาพเคลื่อนไหวที่ทำงานบนรายการที่ เปลี่ยนแปลงเนื่องจากมีรายการใหม่ปรากฏในคอนเทนเนอร์DISAPPEARING
- ธงที่ระบุภาพเคลื่อนไหวที่ทำงานบนรายการที่ หายไปจากคอนเทนเนอร์CHANGE_DISAPPEARING
- ธงที่ระบุภาพเคลื่อนไหวที่ทำงานบนรายการที่ เปลี่ยนแปลงไปเนื่องจากรายการหายไปจากคอนเทนเนอร์
คุณสามารถสร้างภาพเคลื่อนไหวที่กำหนดเองสำหรับเหตุการณ์ทั้ง 4 ประเภทนี้เพื่อปรับแต่งรูปลักษณ์ ของการเปลี่ยนเลย์เอาต์ หรือแค่บอกให้ระบบภาพเคลื่อนไหวใช้ภาพเคลื่อนไหวเริ่มต้นก็ได้
วิธีตั้งค่าแอตทริบิวต์ android:animateLayoutchanges
เป็น true
สำหรับแอตทริบิวต์
ViewGroup ให้ดำเนินการดังนี้
<LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/verticalContainer" android:animateLayoutChanges="true" />
การตั้งค่าแอตทริบิวต์นี้เป็น "จริง" จะทำให้ภาพเคลื่อนไหวของมุมมองที่เพิ่มหรือนำออกจาก ViewGroup รวมถึงข้อมูลพร็อพเพอร์ตี้ที่เหลือใน ViewGroup
สร้างภาพเคลื่อนไหวการเปลี่ยนแปลงสถานะมุมมองโดยใช้ StateListAnimator
คลาส StateListAnimator
จะให้คุณกำหนดภาพเคลื่อนไหวที่เรียกใช้เมื่อ
สถานะของมุมมองจะเปลี่ยนไป ออบเจ็กต์นี้ทำงานเป็น Wrapper สำหรับ
Animator
โดยเรียกใช้ภาพเคลื่อนไหวดังกล่าวเมื่อใดก็ตามที่ระบุ
ดูการเปลี่ยนแปลงสถานะ (เช่น "กด" หรือ "โฟกัส")
คุณกำหนด StateListAnimator
ในทรัพยากร XML ที่มีรูทได้
องค์ประกอบ <selector>
และองค์ประกอบย่อย <item>
ที่แต่ละองค์ประกอบระบุ
สถานะการดูอื่นๆ ที่กำหนดโดยคลาส StateListAnimator
ชิ้น
<item>
มีคําจํากัดความของชุดภาพเคลื่อนไหวของพร็อพเพอร์ตี้
ตัวอย่างเช่น ไฟล์ต่อไปนี้สร้างตัวสร้างภาพเคลื่อนไหวของรายการสถานะที่เปลี่ยนแปลงสเกล x และ y ของมุมมองเมื่อกด
res/xml/animate_scale.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- the pressed state; increase x and y size to 150% --> <item android:state_pressed="true"> <set> <objectAnimator android:propertyName="scaleX" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1.5" android:valueType="floatType"/> <objectAnimator android:propertyName="scaleY" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1.5" android:valueType="floatType"/> </set> </item> <!-- the default, non-pressed state; set x and y size to 100% --> <item android:state_pressed="false"> <set> <objectAnimator android:propertyName="scaleX" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1" android:valueType="floatType"/> <objectAnimator android:propertyName="scaleY" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1" android:valueType="floatType"/> </set> </item> </selector>
หากต้องการแนบตัวสร้างภาพเคลื่อนไหวรายการรัฐลงในมุมมอง ให้เพิ่มพารามิเตอร์
android:stateListAnimator
ดังนี้
<Button android:stateListAnimator="@xml/animate_scale" ... />
ตอนนี้ จะมีการใช้ภาพเคลื่อนไหวที่กำหนดไว้ใน animate_scale.xml
เมื่อของปุ่มนี้
การเปลี่ยนแปลงสถานะ
หรือหากต้องการกำหนดตัวสร้างภาพเคลื่อนไหวรายการสถานะให้กับมุมมองในโค้ดของคุณ ให้ใช้
AnimatorInflater.loadStateListAnimator()
และกำหนดผู้สร้างภาพเคลื่อนไหวให้กับ
โดยใช้เมธอด View.setStateListAnimator()
หรือแทนที่จะทำให้คุณสมบัติของมุมมองเคลื่อนไหวได้ คุณสามารถเล่นภาพเคลื่อนไหวที่ถอนออกได้ระหว่าง
การเปลี่ยนแปลงสถานะ โดยใช้ AnimatedStateListDrawable
วิดเจ็ตระบบบางส่วนใน
Android 5.0 จะใช้ภาพเคลื่อนไหวเหล่านี้โดยค่าเริ่มต้น ตัวอย่างต่อไปนี้จะแสดงวิธีการ
เพื่อกำหนด AnimatedStateListDrawable
เป็นทรัพยากร XML:
<!-- res/drawable/myanimstatedrawable.xml --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- provide a different drawable for each state--> <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" android:state_pressed="true"/> <item android:id="@+id/focused" android:drawable="@drawable/drawableF" android:state_focused="true"/> <item android:id="@id/default" android:drawable="@drawable/drawableD"/> <!-- specify a transition --> <transition android:fromId="@+id/default" android:toId="@+id/pressed"> <animation-list> <item android:duration="15" android:drawable="@drawable/dt1"/> <item android:duration="15" android:drawable="@drawable/dt2"/> ... </animation-list> </transition> ... </animated-selector>
ใช้ TypeEvaluator
คุณสร้างภาพเคลื่อนไหวในประเภทที่ระบบ Android ไม่รู้จักได้
ผู้ประเมินโดยใช้อินเทอร์เฟซ TypeEvaluator
ประเภทที่
ระบบ Android จะรู้จักกันในชื่อ int
, float
หรือสี
รองรับโดยประเภท IntEvaluator
, FloatEvaluator
และ ArgbEvaluator
ผู้ประเมิน
คุณใช้ได้เพียงวิธีเดียวใน TypeEvaluator
อินเทอร์เฟซ เมธอด evaluate()
วิธีนี้ช่วยให้
เครื่องมือสร้างภาพเคลื่อนไหวที่คุณใช้เพื่อแสดงผลค่าที่เหมาะสมสำหรับพร็อพเพอร์ตี้ภาพเคลื่อนไหวที่
ตำแหน่งปัจจุบันของภาพเคลื่อนไหว ชั้นเรียน FloatEvaluator
แสดงให้เห็นว่า
วิธีการมีดังนี้
Kotlin
private class FloatEvaluator : TypeEvaluator<Any> { override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any { return (startValue as Number).toFloat().let { startFloat -> startFloat + fraction * ((endValue as Number).toFloat() - startFloat) } } }
Java
public class FloatEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); } }
หมายเหตุ: เมื่อ ValueAnimator
(หรือ ObjectAnimator
) ทำงาน ระบบจะคำนวณเศษส่วนที่ผ่านไปในปัจจุบันของ
ภาพเคลื่อนไหว (ค่าระหว่าง 0 ถึง 1) แล้วคำนวณรูปแบบการประมาณค่านั้น
คุณกำลังใช้อินเตอร์โพลเตอร์ชนิดใด เศษส่วนที่ประมาณคือสิ่งที่ TypeEvaluator
ได้รับผ่านพารามิเตอร์ fraction
ไม่จำเป็นต้องคำนึงถึงตัวการประมาณค่าในช่วงเมื่อคำนวณค่าแบบเคลื่อนไหว
ใช้อินเตอร์โพเลเตอร์
ตัวกำหนดช่วงของการคำนวณค่าหนึ่งๆ ในภาพเคลื่อนไหวโดยเป็นฟังก์ชันของ เช่น คุณสามารถระบุภาพเคลื่อนไหวให้เกิดขึ้นเป็นเส้นตรงทั่วทั้งภาพเคลื่อนไหว หมายความว่าภาพเคลื่อนไหวจะเคลื่อนที่อย่างเท่าๆ กันตลอดเวลา หรือคุณจะระบุภาพเคลื่อนไหวที่จะใช้ เวลาที่ไม่ใช่เชิงเส้น เช่น การใช้ความเร่งหรือการลดความเร็วที่ช่วงต้นหรือช่วงท้ายของ ภาพเคลื่อนไหว
ตัวแปลงสัญญาณในระบบภาพเคลื่อนไหวจะได้รับเศษส่วนจากแอนิเมเตอร์ที่แสดงถึง
เวลาที่ใช้ไปของภาพเคลื่อนไหว ตัวแปลงกลางจะปรับแต่งเศษส่วนนี้ให้ตรงกับประเภทของ
ภาพเคลื่อนไหวที่วางแผนไว้ ระบบ Android มีชุดอินเตอร์โพเลเตอร์ทั่วไปใน
android.view.animation package
หากไม่มีข้อใดที่ตรงกับ
คุณสามารถใช้อินเทอร์เฟซ TimeInterpolator
และสร้าง
ของตัวเอง
ด้านล่างนี้เป็นตัวอย่างวิธีเปรียบเทียบตัวประมาณค่ากลาง AccelerateDecelerateInterpolator
และ LinearInterpolator
ในการคำนวณเศษส่วนโดยประมาณ
LinearInterpolator
ไม่มีผลต่อเศษส่วนที่ผ่านไป AccelerateDecelerateInterpolator
เร่งความเร็วเข้าสู่ภาพเคลื่อนไหวและ
ก็ค่อยๆ ลดลง เมธอดต่อไปนี้จะกำหนดตรรกะสำหรับตัวแปลค่าเหล่านี้
AccelerateDecelerateInterpolator
Kotlin
override fun getInterpolation(input: Float): Float = (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f
Java
@Override public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; }
LinearInterpolator
Kotlin
override fun getInterpolation(input: Float): Float = input
Java
@Override public float getInterpolation(float input) { return input; }
ตารางต่อไปนี้แสดงค่าโดยประมาณที่คำนวณจาก ตัวกำหนดช่วงสำหรับภาพเคลื่อนไหวที่ยาวนาน 1,000 มิลลิวินาที:
ผ่านไปแล้ว ms | เศษส่วนที่ผ่านไป/เศษส่วนแทรก (เชิงเส้น) | เศษส่วนโดยประมาณ (เร่ง/ลด) |
---|---|---|
0 | 0 | 0 |
200 | .2 | .1 |
400 | .4 | .345 |
600 | 6 วินาที | .8 |
800 | .8 | .9 |
1000 | 1 | 1 |
ตามตารางที่ปรากฏ LinearInterpolator
จะเปลี่ยนค่า
ที่ความเร็วเดียวกัน นั่นคือ 0.2 สำหรับทุก 200 มิลลิวินาทีที่ผ่านไป AccelerateDecelerateInterpolator
จะเปลี่ยนค่าให้เร็วกว่า LinearInterpolator
ระหว่าง 200 ถึง 600 มิลลิวินาที และช้าลงระหว่าง 600 มิลลิวินาทีถึง
1,000 มิลลิวินาที
ระบุคีย์เฟรม
ออบเจ็กต์ Keyframe
ประกอบด้วยคู่เวลา/ค่าที่ช่วยให้คุณกำหนด
สถานะที่เฉพาะเจาะจง ณ เวลาที่เจาะจงของภาพเคลื่อนไหว แต่ละคีย์เฟรมยังสามารถมี
ตัวกำหนดช่วงสำหรับควบคุมลักษณะการทำงานของภาพเคลื่อนไหวในช่วงระหว่าง
เวลาของคีย์เฟรมและเวลาของคีย์เฟรมนี้
หากต้องการสร้างอินสแตนซ์ของออบเจ็กต์ Keyframe
คุณต้องใช้ค่าจากโรงงาน
เมธอด ofInt()
, ofFloat()
หรือ ofObject()
เพื่อรับประเภท Keyframe
ที่เหมาะสม จากนั้นคุณจึงโทร
เมธอด ofKeyframe()
จากโรงงานเพื่อ
รับออบเจ็กต์ PropertyValuesHolder
เมื่อมีออบเจ็กต์แล้ว คุณสามารถ
รับตัวสร้างภาพเคลื่อนไหวโดยการส่งผ่านในออบเจ็กต์ PropertyValuesHolder
และ
เพื่อให้วัตถุเคลื่อนไหวได้ ข้อมูลโค้ดต่อไปนี้แสดงวิธีดำเนินการ
Kotlin
val kf0 = Keyframe.ofFloat(0f, 0f) val kf1 = Keyframe.ofFloat(.5f, 360f) val kf2 = Keyframe.ofFloat(1f, 0f) val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2) ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply { duration = 5000 }
Java
Keyframe kf0 = Keyframe.ofFloat(0f, 0f); Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); Keyframe kf2 = Keyframe.ofFloat(1f, 0f); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2); ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation); rotationAnim.setDuration(5000);
มุมมองแบบเคลื่อนไหว
ระบบภาพเคลื่อนไหวของพร็อพเพอร์ตี้ช่วยให้สามารถเคลื่อนไหวของออบเจ็กต์ View และข้อเสนอได้อย่างมีประสิทธิภาพ ข้อได้เปรียบบางประการเหนือระบบการดูภาพเคลื่อนไหว วิว ระบบภาพเคลื่อนไหวได้เปลี่ยนรูปแบบวัตถุของมุมมองด้วยการเปลี่ยนวิธีการวาดวัตถุนั้น นี่คือ มีการจัดการในคอนเทนเนอร์ของแต่ละข้อมูลพร็อพเพอร์ตี้ เนื่องจากข้อมูลพร็อพเพอร์ตี้นั้นไม่มีพร็อพเพอร์ตี้ให้ปรับเปลี่ยน ซึ่งส่งผลให้มุมมองเป็นภาพเคลื่อนไหว แต่ตัวมุมมองเองไม่มีการเปลี่ยนแปลง ช่วงเวลานี้ ทำให้เกิดพฤติกรรมต่างๆ เช่น วัตถุที่ยังคงอยู่ในตำแหน่งเดิม แม้ว่าจะ วาดในตำแหน่งอื่นบนหน้าจอ ใน Android 3.0 คุณสมบัติใหม่ และ ได้มีการเพิ่มเมธอด Getter และ Setter เพื่อขจัดข้อเสียนี้
ระบบภาพเคลื่อนไหวของพร็อพเพอร์ตี้
ทำให้มุมมองเคลื่อนไหวบนหน้าจอได้โดยเปลี่ยนคุณสมบัติจริงในออบเจ็กต์มุมมอง ใน
นอกจากนี้ View ยังจะเรียกฟังก์ชัน invalidate()
เพื่อรีเฟรชหน้าจอเมื่อใดก็ตามที่มีการเปลี่ยนแปลงคุณสมบัติ พร็อพเพอร์ตี้ใหม่ในคลาส View
ที่สนับสนุนการสร้างภาพเคลื่อนไหวของพร็อพเพอร์ตี้มีดังนี้
translationX
และtranslationY
: พร็อพเพอร์ตี้เหล่านี้ควบคุมว่า มุมมองอยู่ในตำแหน่งเดลต้าจากพิกัดด้านซ้ายและด้านบน ซึ่งกำหนดตามการจัดวาง คอนเทนเนอร์rotation
,rotationX
และrotationY
: พร็อพเพอร์ตี้เหล่านี้ ควบคุมการหมุนในแบบ 2 มิติ (rotation
พร็อพเพอร์ตี้) และ 3 มิติรอบจุด PivotscaleX
และscaleY
: พร็อพเพอร์ตี้เหล่านี้จะควบคุมการปรับขนาด 2 มิติของ ดูรอบๆ จุด PivotpivotX
และpivotY
: พร็อพเพอร์ตี้เหล่านี้จะควบคุมตำแหน่งของ จุดหมุน ซึ่งมีการเปลี่ยนการหมุนและการปรับขนาดเกิดขึ้น โดยค่าเริ่มต้น การเปลี่ยนแนวทางเนื้อหา จุดจะอยู่ตรงกลางของวัตถุx
และy
: คุณสมบัติของยูทิลิตีที่เรียบง่ายเพื่ออธิบาย ตำแหน่งสุดท้ายของมุมมองในคอนเทนเนอร์ ซึ่งเป็นผลรวมของค่าด้านซ้ายและค่าด้านบนและ ค่า X และ translateYalpha
: แสดงความโปร่งใสของอัลฟ่าในมุมมอง ค่านี้คือ 1 (ทึบแสง) โดยค่าเริ่มต้น ซึ่งมีค่า 0 แสดงถึงความโปร่งใสโดยสมบูรณ์ (มองไม่เห็น)
หากต้องการทำให้พร็อพเพอร์ตี้ของออบเจ็กต์มุมมองเคลื่อนไหว เช่น ค่าสีหรือค่าการหมุน สิ่งที่คุณต้องทำ ควรสร้างตัวสร้างการเคลื่อนไหวของพร็อพเพอร์ตี้ และระบุพร็อพเพอร์ตี้ View ที่คุณต้องการ เป็นภาพเคลื่อนไหว เช่น
Kotlin
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)
Java
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการสร้างภาพเคลื่อนไหว โปรดดูส่วนต่างๆ เกี่ยวกับการสร้างภาพเคลื่อนไหวด้วย ValueAnimator และ ObjectAnimator
สร้างภาพเคลื่อนไหวโดยใช้ ViewPropertyAnimator
ViewPropertyAnimator
มีวิธีทำให้หลาย
คุณสมบัติของ View
พร้อมกันโดยใช้ Animator
ที่สำคัญเพียงรายการเดียว
ออบเจ็กต์ ซึ่งมีลักษณะคล้ายกับ ObjectAnimator
เนื่องจากมีการแก้ไข
ค่าที่แท้จริงของคุณสมบัติของมุมมอง แต่จะมีประสิทธิภาพมากกว่าเมื่อทำให้คุณสมบัติจำนวนมากเคลื่อนไหว
ครั้งเดียว นอกจากนี้ รหัสสำหรับการใช้ ViewPropertyAnimator
ยังมีประโยชน์อย่างมาก
กระชับและอ่านง่ายขึ้น ข้อมูลโค้ดต่อไปนี้แสดงความแตกต่างในการใช้
ออบเจ็กต์ ObjectAnimator
รายการ รายการเดียว
ObjectAnimator
และ ViewPropertyAnimator
เมื่อ
การทำให้พร็อพเพอร์ตี้ x
และ y
ของข้อมูลพร็อพเพอร์ตี้เคลื่อนไหวพร้อมกัน
ออบเจ็กต์ ObjectAnimator หลายรายการ
Kotlin
val animX = ObjectAnimator.ofFloat(myView, "x", 50f) val animY = ObjectAnimator.ofFloat(myView, "y", 100f) AnimatorSet().apply { playTogether(animX, animY) start() }
Java
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
One ObjectAnimator
Kotlin
val pvhX = PropertyValuesHolder.ofFloat("x", 50f) val pvhY = PropertyValuesHolder.ofFloat("y", 100f) ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()
Java
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();
ViewPropertyAnimator
Kotlin
myView.animate().x(50f).y(100f)
Java
myView.animate().x(50f).y(100f);
ดูรายละเอียดเพิ่มเติมเกี่ยวกับ ViewPropertyAnimator
ได้ที่นักพัฒนาแอป Android ที่เกี่ยวข้อง
บล็อก
โพสต์
ประกาศภาพเคลื่อนไหวใน XML
ระบบการเคลื่อนไหวของคุณสมบัติช่วยให้คุณประกาศการเคลื่อนไหวของพร็อพเพอร์ตี้ด้วย XML แทนการดำเนินการ เขียนแบบเป็นโปรแกรม คุณจะนำภาพเคลื่อนไหวกลับมาใช้ใหม่ได้ง่ายๆ ด้วยการกำหนดภาพเคลื่อนไหวในรูปแบบ XML ในหลายกิจกรรมและแก้ไขลำดับภาพเคลื่อนไหวได้ง่ายขึ้น
หากต้องการแยกความแตกต่างระหว่างไฟล์ภาพเคลื่อนไหวที่ใช้ API ภาพเคลื่อนไหวของพร็อพเพอร์ตี้ใหม่กับไฟล์ที่ใช้องค์ประกอบ
เฟรมเวิร์กดูภาพเคลื่อนไหวแบบเดิม
ตั้งแต่ Android 3.1 เป็นต้นไป คุณควรบันทึกไฟล์ XML สำหรับภาพเคลื่อนไหวของพร็อพเพอร์ตี้ในไดเรกทอรี res/animator/
คลาสภาพเคลื่อนไหวของพร็อพเพอร์ตี้ต่อไปนี้รองรับการประกาศ XML ด้วยฟังก์ชัน แท็ก XML ต่อไปนี้:
ValueAnimator
-<animator>
ObjectAnimator
-<objectAnimator>
AnimatorSet
-<set>
หากต้องการค้นหาแอตทริบิวต์ที่คุณสามารถใช้ในการประกาศ XML โปรดดูภาพเคลื่อนไหว ทรัพยากร ตัวอย่างต่อไปนี้เล่นภาพเคลื่อนไหวของวัตถุ 2 ชุด ตามลำดับ โดยชุดที่ซ้อนกันชุดแรกจะเล่นภาพเคลื่อนไหวออบเจ็กต์ 2 รายการร่วมกัน ดังนี้
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
เพื่อเรียกใช้ภาพเคลื่อนไหวนี้ คุณต้องเพิ่มทรัพยากร XML ในโค้ดของคุณให้สูงเกินจริงให้เป็นออบเจ็กต์ AnimatorSet
จากนั้นตั้งค่าออบเจ็กต์เป้าหมายสำหรับภาพเคลื่อนไหวทั้งหมด
ก่อนเริ่มตั้งค่าภาพเคลื่อนไหว การเรียกใช้ setTarget()
จะตั้งค่าออบเจ็กต์เป้าหมายเดียวสำหรับผู้เผยแพร่โฆษณาย่อยทั้งหมดของ AnimatorSet
เพื่ออำนวยความสะดวก โค้ดต่อไปนี้แสดงวิธีดำเนินการ
Kotlin
(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply { setTarget(myObject) start() }
Java
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.animator.property_animator); set.setTarget(myObject); set.start();
คุณยังประกาศ ValueAnimator
ใน XML ได้ด้วย เช่น
ที่แสดงในตัวอย่างต่อไปนี้
<animator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:valueType="floatType" android:valueFrom="0f" android:valueTo="-100f" />
หากต้องการใช้ ValueAnimator
ก่อนหน้าในโค้ด คุณต้อง
ต้องทำให้อ็อบเจ็กต์สูงเกินจริง เพิ่ม
AnimatorUpdateListener
,
รับค่าของภาพเคลื่อนไหวที่อัปเดตแล้ว และนำไปใช้ในพร็อพเพอร์ตี้ของมุมมองใดมุมมองหนึ่ง
ดังที่แสดงในรหัสต่อไปนี้
Kotlin
(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply { addUpdateListener { updatedAnimation -> textView.translationX = updatedAnimation.animatedValue as Float } start() }
Java
ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator); xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator updatedAnimation) { float animatedValue = (float)updatedAnimation.getAnimatedValue(); textView.setTranslationX(animatedValue); } }); xmlAnimator.start();
สำหรับข้อมูลเกี่ยวกับไวยากรณ์ XML สำหรับการกำหนดภาพเคลื่อนไหวของพร็อพเพอร์ตี้ โปรดดูภาพเคลื่อนไหว
ผลกระทบที่อาจเกิดขึ้นกับประสิทธิภาพ UI
ภาพเคลื่อนไหวที่อัปเดต UI ทำให้มีการแสดงภาพทุกเฟรมใน ที่ภาพเคลื่อนไหวแสดง ด้วยเหตุนี้ การใช้ภาพเคลื่อนไหวที่ใช้ทรัพยากรจำนวนมาก อาจส่งผลเสียต่อประสิทธิภาพของแอป
ระบบจะเพิ่มงานที่จำเป็นเพื่อทำให้ UI เคลื่อนไหวอยู่ในขั้นตอนของภาพเคลื่อนไหวของ ไปป์ไลน์การแสดงผล คุณสามารถดูได้ว่าภาพเคลื่อนไหวของคุณส่งผลต่อ ประสิทธิภาพของแอปด้วยการเปิดใช้การแสดงผล GPU ของโปรไฟล์ และ การตรวจสอบขั้นของภาพเคลื่อนไหว สำหรับข้อมูลเพิ่มเติม โปรดดู การแสดงผล GPU ของโปรไฟล์ คำแนะนำแบบทีละขั้น