ในบทความนี้จะเจาะจงไปที่การใช้ Property Animation เท่านั้น ไม่รวมไปถึง View Animation นะ

ในการใช้งาน Property Animation ไม่ว่าจะเป็น Object Animator หรือ Value Animator ก็ตาม เบื้องหลังในการทำงานของ Animation เหล่านี้ก็คือการคำนวณค่าตัวเลขโดยเริ่มจาก 0 ไปจนถึง 1 ในระยะเวลาที่นักพัฒนากำหนดไว้ แล้วค่าตัวเลขดังกล่าวก็จะถูกนำไปเป็น Factor ในการกำหนดให้กับ View Property ไม่ว่าจะเป็น Scale, Translator, Rotation หรืออื่นๆ เพื่อให้ออกมาเป็นการเคลื่อนไหวในรูปแบบต่างๆที่นักพัฒนาต้องการ

รู้จักกับ Interpolator

เพื่อให้การใช้ Property Animation มีลูกเล่นมากขึ้น บนแอนดรอยด์ก็มีสิ่งที่เรียกว่า Interpolator เพื่อให้นักพัฒนาสามารถกำหนดรูปแบบในการคำนวณค่าตัวเลขดังกล่าวให้ออกมาเป็นรูปแบบต่างๆ เพื่อให้การเคลื่อนไหวออกมาในลักษณะที่ต้องการได้ โดยมีดังนี้

  • Accelerate Decelerate Interpolator
  • Accelerate Interpolator
  • Anticipate Interpolator
  • Anticipate Overshoot Interpolator
  • Bounce Interpolator
  • Cycle Interpolator
  • Decelerate Interpolator
  • Linear Interpolator
  • Overshoot Interpolator

ถ้าอยากรู้ว่า Interpolator แต่ละตัวทำงานต่างกันอย่างไร ให้ดูที่ภาพนี้ได้เลย

ในกรณีที่นักพัฒนาสร้าง Property Animation ขึ้นมาแต่ไม่ได้กำหนด Interpolator ไว้ ก็จะให้ Linear Interpolator เป็นค่าเริ่มต้น

ซึ่ง Interpolator ก็จะให้ผลจากการคำนวณค่าตัวเลขในแต่ละช่วงเวลาแตกต่างกันออกไป เช่น เปรียบเทียบระหว่าง Linear Interpolator กับ Accelerate Interpolator สำหรับ Object Animator แบบ Scale โดยมีระยะเวลา 2 วินาที

จะเห็นว่า Linear Interpolator มีค่าตัวเลขเพิ่มแบบคงที่ ส่วน Accelerate Interpolator นั้น ค่าตัวเลขจะเพิ่มขึ้นน้อยกว่าในช่วงแรกๆ และเพิ่มเยอะขึ้นในช่วงท้ายๆ

ดังนั้นการกำหนด Interpolator ที่เหมาะสมจะช่วยทำให้ Animation ของ View ดูเป็นธรรมชาติมากขึ้น ลื่นไหลสบายตามากขึ้น นักพัฒนาจึงควรเลือกใช้ให้เหมาะสมกับแต่ละสถานการณ์

การกำหนด Interpolator ให้กับ Property Animation

เนื่องจากการสร้าง Property Animation สามารถทำได้ทั้งแบบ Animation Resource และ Programmatically ดังนั้น Interpolator จึงสามารถกำหนดได้ทั้ง 2แบบเช่นกัน

การใช้งาน Interpolator ใน Animation Resource จะต้องเรียกจาก @android:anim เท่านั้น

<!-- res/animator/bouncy_drop.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="1000"
        android:interpolator="@android:anim/bounce_interpolator"
        android:propertyName="translationY"
        android:valueFrom="0"
        android:valueTo="300"
        android:valueType="floatType" />
</set>

โดย Interpolator ที่สามารถเรียกใช้งานผ่าน Animation Resource ได้ จะมีทั้งหมดดังนี้

  • @android:anim/accelerate_decelerate_interpolator
  • @android:anim/accelerate_interpolator
  • @android:anim/anticipate_interpolator
  • @android:anim/anticipate_overshoot_interpolator
  • @android:anim/bounce_interpolator
  • @android:anim/cycle_interpolator
  • @android:anim/decelerate_interpolator
  • @android:anim/linear_interpolator
  • @android:anim/overshoot_interpolator

ส่วนการกำหนด Interpolator ผ่าน Programmatically จะเป็นการสร้าง Instance ขึ้นมาเหมือนกับคลาสทั่วๆไป

val view: View = /* ... */
val dropAnimator = ObjectAnimator.ofFloat(
    view,
    View.TRANSLATION_Y,
    300f
).apply {
    duration = 1000
    interpolator = BounceInterpolator()
}

โดยการสร้างแบบ Programmatically นั้นจะมี Interpolator บางตัวที่นักพัฒนาสามารถกำหนด Factor เองได้อีกด้วย

Interpolator ที่มีอยู่ไม่ถูกใจ? สร้างขึ้นมาเองเลยสิ

ในบางครั้ง Interpolator ที่มีให้ใน API อาจจะไม่ตรงกับความต้องการ จึงทำให้ Interpolator ออกแบบมาให้นักพัฒนาสามารถสร้างขึ้นมาได้เองตามใจชอบ ขอแค่คลาสนั้นๆสร้างขึ้นมาจาก​ TimeInterpolator ก็พอ

class CustomInterpolator : TimeInterpolator {
    override fun getInterpolation(input: Float): Float {
        return (cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f
    }
}

โดย TimeInterpolator เป็น Interface ที่มี Overide Method ที่ชื่อว่า getInterpolation(input: Float) เพื่อให้นักพัฒนารับค่า 0 - 1 ตามช่วงเวลาของ Animation เพื่อนำไปคำนวณยังไงก็ได้ แล้วส่งค่าออกมาเป็น Float ที่อยู่ในระหว่าง 0 - 1

แต่ทว่าเรื่องมันเศร้าตรงที่ การสร้าง Interpolator ขึ้นมาเองจะไม่สามารถใช้กับ Animation Resource ได้นั่นเอง ต้องประกาศผ่านโค้ดแบบ Programmatically เท่านั้น

สรุป

Interpolator นั้นถูกออกแบบมาเพื่อเพิ่มประสิทธิภาพให้กับ Property Animation ให้มากขึ้น เพื่อให้การเคลื่อนไหวมีความหลากหลาย และดูสมจริงมากขึ้น โดยนักพัฒนาสามารถเลือก Interpolator ที่เหมาะสมไปใช้งานได้ตามต้องการ หรือจะสร้างขึ้นมาเองก็ได้เช่นกัน

แหล่งข้อมูลอ้างอิง