สร้างภาพเคลื่อนไหวของการเคลื่อนไหวโดยใช้สปริงฟิสิกส์

ลองใช้วิธีแบบ Compose
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีใช้ภาพเคลื่อนไหวใน Compose

การเคลื่อนไหว ตามหลักฟิสิกส์เกิดจากแรง แรงสปริงเป็นแรงอย่างหนึ่งที่กำหนด การโต้ตอบและการเคลื่อนไหว แรงสปริงมีคุณสมบัติดังต่อไปนี้ การหน่วงและการแข็ง ในภาพเคลื่อนไหวแบบสปริง ระบบจะคำนวณค่าและความเร็วตามแรงสปริงที่ใช้กับแต่ละเฟรม

หากต้องการให้ภาพเคลื่อนไหวของแอปช้าลงในทิศทางเดียวเท่านั้น ให้พิจารณาใช้ภาพเคลื่อนไหวแบบสะบัด ที่อิงตามแรงเสียดทานแทน

วงจรของแอนิเมชันแรงสปริง

ในภาพเคลื่อนไหวแบบสปริง คลาส SpringForce ช่วยให้คุณปรับแต่งความแข็งของสปริง อัตราส่วนการหน่วง และ ตำแหน่งสุดท้ายได้ ทันทีที่ภาพเคลื่อนไหวเริ่มขึ้น แรงสปริงจะอัปเดต ค่าภาพเคลื่อนไหวและความเร็วในแต่ละเฟรม ภาพเคลื่อนไหวจะดำเนินต่อไป จนกว่าแรงสปริงจะถึงจุดสมดุล

ตัวอย่างเช่น หากคุณลากไอคอนแอปไปรอบๆ หน้าจอ แล้วปล่อยไอคอน โดยยกนิ้วออกจากไอคอน ไอคอนจะดึงกลับไปยังตำแหน่งเดิม ด้วยแรงที่มองไม่เห็นแต่คุ้นเคย

รูปที่ 1 แสดงให้เห็นถึงเอฟเฟกต์สปริงที่คล้ายกัน เครื่องหมายบวก (+) ตรงกลางวงกลมแสดงถึงแรงที่ใช้ผ่านท่าทางสัมผัส

รุ่นฤดูใบไม้ผลิ
รูปที่ 1 ผลจากการเปิดตัวในฤดูใบไม้ผลิ

สร้างภาพเคลื่อนไหวแรงสปริง

ขั้นตอนทั่วไปในการสร้างแอนิเมชันแรงสปริงสำหรับแอปพลิเคชันมีดังนี้

ส่วนต่อไปนี้จะอธิบายขั้นตอนทั่วไปในการสร้างภาพเคลื่อนไหวสปริง โดยละเอียด

เพิ่มคลังการสนับสนุน

หากต้องการใช้ไลบรารีการสนับสนุนตามฟิสิกส์ คุณต้องเพิ่มไลบรารีการสนับสนุนลงในโปรเจ็กต์ ดังนี้

  1. เปิดไฟล์ build.gradle สำหรับโมดูลแอป
  2. เพิ่มไลบรารีการสนับสนุนลงในส่วน dependencies

    ดึงดูด

            dependencies {
                def dynamicanimation_version = '1.0.0'
                implementation "androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version"
            }
            

    Kotlin

            dependencies {
                val dynamicanimation_version = "1.0.0"
                implementation("androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version")
            }
            

    หากต้องการดูเวอร์ชันปัจจุบันของไลบรารีนี้ โปรดดูข้อมูลเกี่ยวกับ Dynamicanimation ในหน้าเวอร์ชัน

สร้างแอนิเมชันแรงสปริง

SpringAnimation คลาสช่วยให้คุณสร้าง ภาพเคลื่อนไหวสปริงสำหรับออบเจ็กต์ได้ หากต้องการสร้างภาพเคลื่อนไหวแบบสปริง คุณต้อง สร้างอินสแตนซ์ของคลาส SpringAnimation และระบุออบเจ็กต์ พร็อพเพอร์ตี้ของออบเจ็กต์ที่ต้องการทำให้เคลื่อนไหว และ ตำแหน่งสปริงสุดท้ายที่ไม่บังคับซึ่งคุณต้องการให้ภาพเคลื่อนไหวหยุด

หมายเหตุ: ในขณะที่สร้างภาพเคลื่อนไหวสปริง คุณจะระบุตำแหน่งสุดท้ายของสปริงหรือไม่ก็ได้ แต่คุณต้องกำหนดค่าก่อนเริ่มภาพเคลื่อนไหว

Kotlin

val springAnim = findViewById<View>(R.id.imageView).let { img ->
    // Setting up a spring animation to animate the view’s translationY property with the final
    // spring position at 0.
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0f)
}

Java

final View img = findViewById(R.id.imageView);
// Setting up a spring animation to animate the view’s translationY property with the final
// spring position at 0.
final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);

ภาพเคลื่อนไหวแบบสปริงสามารถทำให้มุมมองบนหน้าจอเคลื่อนไหวได้โดยการเปลี่ยน คุณสมบัติจริงในออบเจ็กต์มุมมอง มุมมองต่อไปนี้พร้อมใช้งานใน ระบบ

  • ALPHA: แสดงถึงความโปร่งแสงอัลฟ่าในมุมมอง ค่าเริ่มต้นคือ 1 (ทึบแสง) โดยค่า 0 หมายถึงความโปร่งใสทั้งหมด (มองไม่เห็น)
  • TRANSLATION_X, TRANSLATION_Y และ TRANSLATION_Z: พร็อพเพอร์ตี้เหล่านี้ จะควบคุมตำแหน่งของมุมมองเป็นเดลต้าจากพิกัดซ้าย พิกัดบน และระดับความสูง ซึ่งกำหนดโดยคอนเทนเนอร์เลย์เอาต์
    • TRANSLATION_X อธิบายพิกัดซ้าย
    • TRANSLATION_Y อธิบายพิกัดบนสุด
    • TRANSLATION_Z อธิบายความลึกของมุมมองที่สัมพันธ์กับระดับความสูง
  • ROTATION ROTATION_X และ ROTATION_Y: พร็อพเพอร์ตี้เหล่านี้ ควบคุมการหมุนใน 2 มิติ (พร็อพเพอร์ตี้ rotation) และ 3 มิติรอบจุดหมุน
  • SCROLL_X และ SCROLL_Y: คุณสมบัติเหล่านี้ ระบุออฟเซ็ตการเลื่อนของขอบด้านซ้ายและด้านบนของแหล่งที่มา เป็นพิกเซล นอกจากนี้ ยังระบุตำแหน่งในแง่ของปริมาณการเลื่อนหน้าเว็บด้วย
  • SCALE_X และ SCALE_Y: พร็อพเพอร์ตี้เหล่านี้ ควบคุมการปรับขนาด 2 มิติของมุมมองรอบจุดหมุน
  • X Y และ Z: เป็นพร็อพเพอร์ตี้ ยูทิลิตีพื้นฐานที่ใช้อธิบายตำแหน่งสุดท้ายของมุมมองในคอนเทนเนอร์
    • X คือผลรวมของค่าทางด้านซ้ายและ TRANSLATION_X
    • Y คือผลรวมของ ค่าสูงสุดและ TRANSLATION_Y
    • Z คือผลรวมของค่า ระดับความสูงและ TRANSLATION_Z

ลงทะเบียน Listener

คลาส DynamicAnimation มี Listener 2 รายการ ได้แก่ OnAnimationUpdateListener และ OnAnimationEndListener โดย Listener เหล่านี้จะรับฟังการอัปเดตในภาพเคลื่อนไหว เช่น เมื่อมีการเปลี่ยนแปลงค่าภาพเคลื่อนไหวและเมื่อภาพเคลื่อนไหวสิ้นสุดลง

OnAnimationUpdateListener

เมื่อต้องการทำให้มุมมองหลายรายการเคลื่อนไหวเพื่อสร้างภาพเคลื่อนไหวแบบลูกโซ่ คุณ สามารถตั้งค่า OnAnimationUpdateListener ให้รับการเรียกกลับทุกครั้งที่มีการเปลี่ยนแปลงพร็อพเพอร์ตี้ของมุมมองปัจจุบันได้ โดยการเรียกกลับจะแจ้งให้มุมมองอื่นอัปเดตตำแหน่งสปริง ตามการเปลี่ยนแปลงที่เกิดขึ้นในพร็อพเพอร์ตี้ของมุมมองปัจจุบัน หากต้องการลงทะเบียน Listener ให้ทำตามขั้นตอนต่อไปนี้

  1. เรียกใช้เมธอด addUpdateListener() และแนบ Listener ไปกับภาพเคลื่อนไหว

    หมายเหตุ: คุณต้องลงทะเบียนเครื่องมือฟังการอัปเดต ก่อนที่ภาพเคลื่อนไหวจะเริ่ม อย่างไรก็ตาม ควรลงทะเบียนเครื่องมือฟังการอัปเดตเฉพาะในกรณีที่คุณต้องการอัปเดตค่าภาพเคลื่อนไหวต่อเฟรมเมื่อมีการเปลี่ยนแปลง เครื่องมือฟังการอัปเดตจะป้องกันไม่ให้ภาพเคลื่อนไหว อาจทำงานในเธรดแยกต่างหาก

  2. แทนที่เมธอด onAnimationUpdate() เพื่อแจ้งให้ผู้เรียกทราบเกี่ยวกับการเปลี่ยนแปลงในออบเจ็กต์ปัจจุบัน โค้ดตัวอย่างต่อไปนี้แสดงการใช้งานโดยรวมของ OnAnimationUpdateListener

Kotlin

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
val (anim1X, anim1Y) = findViewById<View>(R.id.view1).let { view1 ->
    SpringAnimation(view1, DynamicAnimation.TRANSLATION_X) to
            SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y)
}
val (anim2X, anim2Y) = findViewById<View>(R.id.view2).let { view2 ->
    SpringAnimation(view2, DynamicAnimation.TRANSLATION_X) to
            SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y)
}

// Registering the update listener
anim1X.addUpdateListener { _, value, _ ->
    // Overriding the method to notify view2 about the change in the view1’s property.
    anim2X.animateToFinalPosition(value)
}

anim1Y.addUpdateListener { _, value, _ -> anim2Y.animateToFinalPosition(value) }

Java

// Creating two views to demonstrate the registration of the update listener.
final View view1 = findViewById(R.id.view1);
final View view2 = findViewById(R.id.view2);

// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties
final SpringAnimation anim1X = new SpringAnimation(view1,
        DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim1Y = new SpringAnimation(view1,
    DynamicAnimation.TRANSLATION_Y);
final SpringAnimation anim2X = new SpringAnimation(view2,
        DynamicAnimation.TRANSLATION_X);
final SpringAnimation anim2Y = new SpringAnimation(view2,
        DynamicAnimation.TRANSLATION_Y);

// Registering the update listener
anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

// Overriding the method to notify view2 about the change in the view1’s property.
    @Override
    public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                  float velocity) {
        anim2X.animateToFinalPosition(value);
    }
});

anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {

  @Override
    public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
                                  float velocity) {
        anim2Y.animateToFinalPosition(value);
    }
});

OnAnimationEndListener

OnAnimationEndListener จะแจ้งให้ทราบเมื่อภาพเคลื่อนไหวสิ้นสุด คุณตั้งค่า Listener เพื่อรับ Callback ได้ทุกเมื่อที่ภาพเคลื่อนไหวถึงจุดสมดุลหรือถูกยกเลิก หากต้องการ ลงทะเบียน Listener ให้ทำตามขั้นตอนต่อไปนี้

  1. เรียกใช้เมธอด addEndListener() และแนบ Listener ไปกับภาพเคลื่อนไหว
  2. แทนที่เมธอด onAnimationEnd() เพื่อรับการแจ้งเตือนทุกครั้งที่ภาพเคลื่อนไหวถึงจุดสมดุล หรือถูกยกเลิก

นำผู้ฟังออก

หากต้องการหยุดรับการเรียกกลับการอัปเดตภาพเคลื่อนไหวและการเรียกกลับการสิ้นสุดภาพเคลื่อนไหว ให้เรียกใช้เมธอด removeUpdateListener() และ removeEndListener() ตามลำดับ

ตั้งค่าเริ่มต้นของภาพเคลื่อนไหว

หากต้องการตั้งค่าเริ่มต้นของภาพเคลื่อนไหว ให้เรียกใช้เมธอด setStartValue() และส่งค่าเริ่มต้นของภาพเคลื่อนไหว หากไม่ได้ตั้งค่า ค่าเริ่มต้น ภาพเคลื่อนไหวจะใช้ค่าปัจจุบันของพร็อพเพอร์ตี้ของออบเจ็กต์ เป็นค่าเริ่มต้น

กำหนดช่วงค่าของภาพเคลื่อนไหว

คุณกำหนดค่าภาพเคลื่อนไหวต่ำสุดและสูงสุดได้เมื่อต้องการ จำกัดค่าพร็อพเพอร์ตี้ให้อยู่ในช่วงที่กำหนด นอกจากนี้ยังช่วยควบคุม ช่วงในกรณีที่คุณเคลื่อนไหวพร็อพเพอร์ตี้ที่มีช่วงโดยธรรมชาติ เช่น อัลฟ่า (จาก 0 ถึง 1)

  • หากต้องการตั้งค่าต่ำสุด ให้เรียกใช้เมธอด setMinValue() และส่งค่าต่ำสุดของพร็อพเพอร์ตี้
  • หากต้องการตั้งค่าสูงสุด ให้เรียกใช้เมธอด setMaxValue() และส่งค่าสูงสุดของพร็อพเพอร์ตี้

ทั้ง 2 วิธีจะแสดงผลภาพเคลื่อนไหวที่มีการตั้งค่า

หมายเหตุ: หากคุณตั้งค่าเริ่มต้นและกำหนดช่วงค่าภาพเคลื่อนไหว แล้ว ให้ตรวจสอบว่าค่าเริ่มต้นอยู่ในช่วงค่าต่ำสุดและสูงสุด

ตั้งค่าความเร็วเริ่มต้น

ความเร็วเริ่มต้นจะกำหนดความเร็วที่พร็อพเพอร์ตี้ภาพเคลื่อนไหวเปลี่ยนที่ จุดเริ่มต้นของภาพเคลื่อนไหว ความเร็วเริ่มต้นเริ่มต้นจะตั้งค่าเป็น 0 พิกเซลต่อวินาที คุณตั้งค่าความเร็วได้โดยใช้ความเร็วของท่าทางสัมผัส หรือใช้ค่าคงที่เป็นความเร็วเริ่มต้น หากเลือก ระบุค่าคงที่ เราขอแนะนําให้กําหนดค่าเป็น dp ต่อวินาที แล้ว แปลงเป็นพิกเซลต่อวินาที การกำหนดค่าใน dp ต่อวินาที ช่วยให้อัตราความเร็วไม่ขึ้นอยู่กับความหนาแน่นและรูปแบบของอุปกรณ์ ดูข้อมูลเพิ่มเติม เกี่ยวกับการแปลงค่าเป็นพิกเซลต่อวินาทีได้ที่ส่วนการแปลง dp ต่อวินาทีเป็นพิกเซลต่อวินาที

หากต้องการตั้งค่าความเร็ว ให้เรียกใช้เมธอด setStartVelocity() และส่งความเร็วเป็นพิกเซลต่อวินาที เมธอดจะแสดงผลออบเจ็กต์แรงสปริง ซึ่งมีการตั้งค่าความเร็ว

หมายเหตุ: ใช้เมธอดคลาส GestureDetector.OnGestureListener หรือ VelocityTracker เพื่อดึงและคำนวณ ความเร็วของท่าทางสัมผัส

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Compute velocity in the unit pixel/second
        vt.computeCurrentVelocity(1000)
        val velocity = vt.yVelocity
        setStartVelocity(velocity)
    }
}

Java

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Compute velocity in the unit pixel/second
vt.computeCurrentVelocity(1000);
float velocity = vt.getYVelocity();
anim.setStartVelocity(velocity);

การแปลง dp ต่อวินาทีเป็นพิกเซลต่อวินาที

ความเร็วของสปริงต้องเป็นพิกเซลต่อวินาที หากเลือกที่จะระบุ ค่าอยู่กับที่เป็นจุดเริ่มต้นของอัตราความเร็ว ให้ระบุค่าเป็น dp ต่อวินาที แล้วแปลงเป็นพิกเซลต่อวินาที สําหรับการแปลง ให้ใช้วิธี applyDimension() จากคลาส TypedValue ดูโค้ดตัวอย่างต่อไปนี้

Kotlin

val pixelPerSecond: Float =
    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, resources.displayMetrics)

Java

float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

ตั้งค่าพร็อพเพอร์ตี้ของ Spring

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

เคล็ดลับ: ขณะใช้วิธีการ Setter คุณสามารถ สร้างเชนของเมธอดเนื่องจากเมธอด Setter ทั้งหมดจะส่งคืนออบเจ็กต์แรงสปริง

อัตราส่วนการลดทอน

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

  • การหน่วงมากเกินไปจะเกิดขึ้นเมื่ออัตราส่วนการหน่วงมากกว่า 1 ซึ่งจะช่วยให้ ออบเจ็กต์กลับสู่ตำแหน่งพักอย่างนุ่มนวล
  • การหน่วงวิกฤตจะเกิดขึ้นเมื่ออัตราส่วนการหน่วงเท่ากับ 1 ซึ่งจะช่วยให้ ออบเจ็กต์กลับสู่ตำแหน่งพักได้ภายในเวลาที่สั้นที่สุด
  • การหน่วงต่ำเกิดขึ้นเมื่ออัตราส่วนการหน่วงน้อยกว่า 1 ซึ่งจะช่วยให้ ออบเจ็กต์เคลื่อนที่เกินตำแหน่งพักหลายครั้งโดยผ่านตำแหน่งพัก แล้ว ค่อยๆ กลับมาที่ตำแหน่งพัก
  • การหน่วงเป็น 0 เกิดขึ้นเมื่ออัตราส่วนการหน่วงเท่ากับ 0 ซึ่งจะทำให้ ออบเจ็กต์สั่นตลอดไป

หากต้องการเพิ่มอัตราส่วนการหน่วงไปยังสปริง ให้ทำตามขั้นตอนต่อไปนี้

  1. เรียกใช้เมธอด getSpring() เพื่อดึงสปริงที่จะเพิ่มอัตราส่วนการลดทอน
  2. เรียกใช้เมธอด setDampingRatio() และส่งผ่านอัตราส่วนการหน่วงที่ต้องการเพิ่มลงในสปริง เมธอด จะแสดงผลออบเจ็กต์แรงสปริงที่มีการตั้งค่าอัตราส่วนการลดทอน

    หมายเหตุ: อัตราส่วนการลดทอนต้องเป็นตัวเลขที่ไม่ใช่ค่าลบ หากตั้งค่าอัตราการลดทอนเป็น 0 สปริงจะ ไม่ถึงตำแหน่งพัก กล่าวคือจะสั่นตลอดไป

ค่าคงที่อัตราส่วนการลดทอนต่อไปนี้มีอยู่ในระบบ

รูปที่ 2: การตีกลับสูง

รูปที่ 3: การตีกลับปานกลาง

รูปที่ 4: อัตราตีกลับต่ำ

รูปที่ 5: ไม่มีการตีกลับ

อัตราส่วนการลดทอนเริ่มต้นจะตั้งไว้ที่ DAMPING_RATIO_MEDIUM_BOUNCY

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Setting the damping ratio to create a low bouncing effect.
        spring.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
        
    }
}

Java

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Setting the damping ratio to create a low bouncing effect.
anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);

ความแข็ง

ความแข็งจะกำหนดค่าคงที่ของสปริง ซึ่งวัดความแข็งแรงของ สปริง สปริงที่แข็งจะออกแรงกับวัตถุที่ติดอยู่มากขึ้น เมื่อสปริงไม่ได้อยู่ในตำแหน่งพัก หากต้องการเพิ่มความแข็งให้กับสปริง ให้ทำตามขั้นตอนต่อไปนี้

  1. เรียกใช้เมธอด getSpring() เพื่อดึงสปริงที่จะเพิ่มความแข็ง
  2. เรียกใช้เมธอด setStiffness() และส่งค่าความแข็งที่ต้องการเพิ่มลงในสปริง เมธอด จะแสดงผลออบเจ็กต์แรงสปริงที่มีการตั้งค่าความแข็ง

    หมายเหตุ: ความแข็งต้องเป็น จำนวนบวก

ค่าคงที่ความแข็งต่อไปนี้พร้อมใช้งานในระบบ

รูปที่ 6: ความแข็งสูง

รูปที่ 7: ความแข็งปานกลาง

รูปที่ 8: ความแข็งต่ำ

รูปที่ 9: ความแข็งต่ำมาก

ความแข็งเริ่มต้นจะตั้งไว้ที่ STIFFNESS_MEDIUM

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Setting the spring with a low stiffness.
        spring.stiffness = SpringForce.STIFFNESS_LOW
        
    }
}

Java

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Setting the spring with a low stiffness.
anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW);

สร้างแรงสปริงที่กำหนดเอง

คุณสร้างแรงสปริงที่กำหนดเองเพื่อใช้แทนแรงสปริงเริ่มต้นได้ แรงสปริงที่กำหนดเองช่วยให้คุณแชร์อินสแตนซ์แรงสปริงเดียวกัน ในภาพเคลื่อนไหวสปริงหลายรายการได้ เมื่อสร้างแรงสปริงแล้ว คุณจะตั้งค่าพร็อพเพอร์ตี้ เช่น อัตราส่วนการหน่วงและความแข็งได้

  1. สร้างออบเจ็กต์ SpringForce

    SpringForce force = new SpringForce();

  2. กำหนดพร็อพเพอร์ตี้โดยเรียกใช้เมธอดที่เกี่ยวข้อง นอกจากนี้ คุณยัง สร้างเชนของเมธอดได้ด้วย

    force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

  3. เรียกใช้เมธอด setSpring() เพื่อตั้งค่าสปริงให้กับภาพเคลื่อนไหว

    setSpring(force);

เริ่มภาพเคลื่อนไหว

คุณเริ่มแอนิเมชันแรงสปริงได้ 2 วิธี ได้แก่ เรียกใช้เมธอด start() หรือเรียกใช้เมธอด animateToFinalPosition() ต้องเรียกใช้ทั้ง 2 วิธีในเธรดหลัก

animateToFinalPosition() จะทำงาน 2 อย่าง ได้แก่

  • กำหนดตำแหน่งสุดท้ายของสปริง
  • เริ่มภาพเคลื่อนไหวหากยังไม่ได้เริ่ม

เนื่องจากเมธอดจะอัปเดตตำแหน่งสุดท้ายของสปริงและเริ่มภาพเคลื่อนไหวหากจำเป็น คุณจึงเรียกเมธอดนี้ได้ทุกเมื่อเพื่อเปลี่ยนเส้นทางของภาพเคลื่อนไหว เช่น ในแอนิเมชันแรงสปริงแบบต่อกัน ภาพเคลื่อนไหวของมุมมองหนึ่งจะขึ้นอยู่กับอีกมุมมองหนึ่ง สำหรับภาพเคลื่อนไหวดังกล่าว การใช้เมธอด animateToFinalPosition() จะสะดวกกว่า การใช้วิธีนี้ในแอนิเมชันแรงสปริงแบบลูกโซ่จะช่วยให้คุณไม่ต้องกังวลว่าภาพเคลื่อนไหวที่ต้องการอัปเดตถัดไปกำลังทำงานอยู่หรือไม่

รูปที่ 10 แสดงแอนิเมชันแรงสปริงแบบเชน ซึ่งแอนิเมชันของมุมมองหนึ่งขึ้นอยู่กับอีกมุมมองหนึ่ง

การสาธิตสปริงที่เชื่อมต่อกัน
รูปที่ 10 การสาธิตสปริงแบบต่อกัน

หากต้องการใช้เมธอด animateToFinalPosition() ให้เรียกใช้เมธอด animateToFinalPosition() และส่งตำแหน่งที่เหลือของสปริง นอกจากนี้ คุณยังตั้งค่าตำแหน่ง ที่เหลือของสปริงได้โดยเรียกใช้เมธอด setFinalPosition()

เมธอด start() จะไม่ตั้งค่าพร็อพเพอร์ตี้เป็นค่าเริ่มต้นทันที ค่าของพร็อพเพอร์ตี้ จะเปลี่ยนไปในแต่ละพัลส์ของภาพเคลื่อนไหว ซึ่งเกิดขึ้นก่อนการส่งผ่านการวาด ด้วยเหตุนี้ การเปลี่ยนแปลงจึงแสดงในเฟรมถัดไปราวกับว่า มีการตั้งค่าทันที

Kotlin

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        
        // Starting the animation
        start()
        
    }
}

Java

final View img = findViewById(R.id.imageView);
final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y);

// Starting the animation
anim.start();

ยกเลิกภาพเคลื่อนไหว

คุณสามารถยกเลิกหรือข้ามไปยังตอนท้ายของภาพเคลื่อนไหวได้ สถานการณ์ที่เหมาะสม ซึ่งคุณต้องยกเลิกหรือข้ามไปยังตอนท้ายของภาพเคลื่อนไหวคือเมื่อผู้ใช้ โต้ตอบและต้องการให้ภาพเคลื่อนไหวสิ้นสุดลงทันที โดยส่วนใหญ่จะเกิดขึ้นเมื่อผู้ใช้ออกจากแอปอย่างกะทันหันหรือมุมมองกลายเป็นมองไม่เห็น

คุณใช้ 2 วิธีต่อไปนี้เพื่อสิ้นสุดภาพเคลื่อนไหวได้ เมธอด cancel() จะสิ้นสุดภาพเคลื่อนไหวที่ค่าปัจจุบัน ส่วนเมธอด skipToEnd() จะข้ามภาพเคลื่อนไหวไปยังค่าสุดท้ายแล้วสิ้นสุด

ก่อนที่จะหยุดภาพเคลื่อนไหว คุณควรตรวจสอบสถานะของสปริงก่อน หากสถานะไม่หน่วง ภาพเคลื่อนไหวจะไม่มีวันไปถึง ตำแหน่งพัก หากต้องการตรวจสอบสถานะของสปริง ให้เรียกใช้เมธอด canSkipToEnd() หาก สปริงมีการหน่วง วิธีการจะแสดงผล true ไม่เช่นนั้น false

เมื่อทราบสถานะของสปริงแล้ว คุณจะสิ้นสุดภาพเคลื่อนไหวได้โดย ใช้เมธอดskipToEnd()หรือเมธอดcancel() ต้องเรียกใช้เมธอด cancel() ในเธรดหลักเท่านั้น

หมายเหตุ: โดยทั่วไปแล้ว วิธี skipToEnd() จะทำให้ เกิดการกระโดดของภาพ