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

ลองใช้วิธีการเขียน
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")
            }
            

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

สร้างภาพเคลื่อนไหวฤดูใบไม้ผลิ

ชั้นเรียน 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 มิติรอบจุด Pivot
  • SCROLL_X และ SCROLL_Y: ตัวเลือกเหล่านี้ จะระบุออฟเซ็ตการเลื่อนของแหล่งที่มาทางซ้ายและขอบด้านบน เป็นพิกเซล และยังระบุตำแหน่งในปริมาณที่หน้าเว็บ เลื่อนแล้ว
  • SCALE_X และ SCALE_Y: ตัวเลือกเหล่านี้ คุณสมบัติดังกล่าวจะควบคุมการปรับขนาด 2 มิติของมุมมองรอบจุด Pivot
  • X, Y และ Z: นี่คือข้อมูลเบื้องต้น คุณสมบัติด้านสาธารณูปโภคที่ใช้อธิบายตำแหน่งสุดท้ายของมุมมอง คอนเทนเนอร์
    • X เป็นผลรวมของ ค่าด้านซ้ายและ TRANSLATION_X
    • Y เป็นผลรวมของ ค่าสูงสุดและ TRANSLATION_Y
    • Z เป็นผลรวมของ ค่าระดับความสูงและ TRANSLATION_Z

ลงทะเบียน Listener

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

OnAnimationUpdateListener

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

  1. โทรหา addUpdateListener() และแนบ Listener เข้ากับภาพเคลื่อนไหว

    หมายเหตุ: คุณต้องลงทะเบียนการอัปเดต Listener ก่อนที่ภาพเคลื่อนไหวจะเริ่มต้น แต่การอัปเดต Listener ควร จะลงทะเบียนก็ต่อเมื่อคุณต้องอัปเดตค่าภาพเคลื่อนไหวต่อเฟรม การเปลี่ยนแปลง 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);
    }
});

EndListener ของ OnAnimation

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

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

นำ Listener ออก

หากต้องการหยุดรับ Callback การอัปเดตภาพเคลื่อนไหวและ Callback สิ้นสุดภาพเคลื่อนไหว โทรติดต่อ 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());

ตั้งค่าคุณสมบัติของฤดูใบไม้ผลิ

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

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

อัตราส่วนความหน่วง

อัตราส่วนการหน่วงจะอธิบายว่าการเด้งตัวขึ้นในฤดูใบไม้ผลิค่อยๆ ลดลง โดย ด้วยการใช้อัตราส่วนการหน่วง คุณจะระบุความเร็วในการลดลงของการเด้งตัวลงได้ จากจุดหนึ่งไปอีกหน้าหนึ่ง คุณลดความหน่วงได้ 4 วิธี ฤดูใบไม้ผลิ:

  • การหน่วงเวลามากเกินไปจะเกิดขึ้นเมื่ออัตราส่วนการหน่วงเวลามากกว่า 1 ซึ่งช่วยให้ ค่อยๆ กลับไปที่ตำแหน่งที่เหลือ
  • การหน่วงที่สำคัญจะเกิดขึ้นเมื่ออัตราส่วนการหน่วงเวลาเท่ากับ 1 ซึ่งช่วยให้ วัตถุจะกลับไปอยู่ที่ตำแหน่งที่เหลือภายในระยะเวลาที่สั้นที่สุด
  • การหน่วงความชื้นจะเกิดขึ้นเมื่ออัตราส่วนการหน่วงเสียงน้อยกว่า 1 ซึ่งช่วยให้ ยิงวัตถุโอเวอร์หลายครั้งโดยผ่านตำแหน่งที่เหลือ จากนั้น จะค่อยๆ ถึงตำแหน่งที่เหลือ
  • การรีดความชื้นจะเกิดขึ้นเมื่ออัตราส่วนการหน่วงเวลาเท่ากับ 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() รายการ การก้าวกระโดดด้วยภาพ