0Pricing
Android Academy · บทเรียน

ภาพเคลื่อนไหวและการเปลี่ยนผ่าน

สร้างภาพเคลื่อนไหวให้มุมมองด้วย ViewPropertyAnimator, ObjectAnimator และ AnimatorSet เพิ่มการเปลี่ยนผ่านของแฟรกเมนต์ ภาพเคลื่อนไหวขององค์ประกอบร่วม และฟิสิกส์แบบสปริง

ภาพเคลื่อนไหวและการเปลี่ยนผ่าน เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 5 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 5 บทเรียน

เหตุใดภาพเคลื่อนไหวจึงสำคัญ

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

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

กฎสำคัญคือ ภาพเคลื่อนไหวควรสนับสนุน UI ไม่ใช่ดึงความสนใจออกไป ควรจำกัดระยะเวลาให้ต่ำกว่า 300 มิลลิวินาที

ViewPropertyAnimator — ภาพเคลื่อนไหวอย่างรวดเร็ว

วิธีที่ง่ายที่สุดในการทำให้มุมมองเคลื่อนไหว เรียกต่อกันเป็นสายแล้วเรียก start():

// Fade a view out:
binding.tvMessage
    .animate()
    .alpha(0f)
    .setDuration(300)
    .withEndAction { binding.tvMessage.visibility = View.GONE }
    .start()

// Slide in from bottom:
binding.cardView.translationY = 200f
binding.cardView.alpha = 0f
binding.cardView
    .animate()
    .translationY(0f)
    .alpha(1f)
    .setDuration(250)
    .setInterpolator(DecelerateInterpolator())
    .start()

ObjectAnimator

ObjectAnimator ทำให้คุณสมบัติใด ๆ ของออบเจ็กต์ใด ๆ เคลื่อนไหวโดยระบุชื่อ ยืดหยุ่นกว่า ViewPropertyAnimator:

// Rotate an image:
val rotateAnimator = ObjectAnimator.ofFloat(
    binding.ivLogo,
    "rotation",
    0f, 360f
).apply {
    duration = 600
    repeatCount = ObjectAnimator.INFINITE
    interpolator = LinearInterpolator()
    start()
}

// Stop it:
rotateAnimator.cancel()

AnimatorSet — แบบต่อเนื่องและแบบขนาน

AnimatorSet ควบคุมตัวทำภาพเคลื่อนไหวหลายตัวให้ทำงานพร้อมกันหรือต่อกันทีละตัว:

val fadeIn  = ObjectAnimator.ofFloat(binding.card, "alpha", 0f, 1f).setDuration(300)
val scaleX  = ObjectAnimator.ofFloat(binding.card, "scaleX", 0.8f, 1f).setDuration(300)
val scaleY  = ObjectAnimator.ofFloat(binding.card, "scaleY", 0.8f, 1f).setDuration(300)
val slideUp = ObjectAnimator.ofFloat(binding.card, "translationY", 100f, 0f).setDuration(300)

AnimatorSet().apply {
    // Run fadeIn + scaleX + scaleY together, then slideUp
    play(fadeIn).with(scaleX).with(scaleY)
    play(slideUp).after(fadeIn)
    interpolator = DecelerateInterpolator()
    start()
}

ตัวปรับจังหวะการเคลื่อนไหว

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

  • LinearInterpolator — ความเร็วคงที่
  • AccelerateInterpolator — เริ่มช้าแล้วเร็วขึ้น (ตอนออก)
  • DecelerateInterpolator — เริ่มเร็วแล้วช้าลง (ตอนเข้า)
  • AccelerateDecelerateInterpolator — ช้า → เร็ว → ช้า (ค่าเริ่มต้น)
  • OvershootInterpolator — เลยเป้าหมายแล้วเด้งกลับ
  • BounceInterpolator — เด้งเมื่อสิ้นสุด

TransitionManager — การเปลี่ยนแปลงเลย์เอาต์

ทำให้การเปลี่ยนแปลงเลย์เอาต์เคลื่อนไหวโดยอัตโนมัติ ด้วยการเรียก TransitionManager.beginDelayedTransition() ก่อนเปลี่ยนการมองเห็นหรือคุณสมบัติของเลย์เอาต์:

binding.btnToggle.setOnClickListener {
    // Tell the framework to animate the next layout change
    TransitionManager.beginDelayedTransition(
        binding.root,
        ChangeBounds().apply { duration = 300 }
    )

    // Now change visibility/size — Android animates the difference automatically
    binding.expandedSection.visibility =
        if (binding.expandedSection.isVisible) View.GONE else View.VISIBLE
}

การเปลี่ยนฉากของ Fragment

เพิ่มภาพเคลื่อนไหวตอนเข้าและตอนออกให้กับธุรกรรมของ fragment:

supportFragmentManager.beginTransaction()
    .setCustomAnimations(
        R.anim.slide_in_right,   // enterAnim
        R.anim.slide_out_left,   // exitAnim
        R.anim.slide_in_left,    // popEnterAnim
        R.anim.slide_out_right   // popExitAnim
    )
    .replace(R.id.container, DetailFragment())
    .addToBackStack(null)
    .commit()

// Or use MaterialSharedAxis for a modern, Material Motion feel:
val forward = MaterialSharedAxis(MaterialSharedAxis.X, true)
exitTransition = forward
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)

การเปลี่ยนฉากขององค์ประกอบร่วม

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

// In ListFragment:
binding.ivThumbnail.transitionName = "hero_image_${item.id}"

val extras = FragmentNavigatorExtras(
    binding.ivThumbnail to "hero_image_${item.id}"
)
findNavController().navigate(R.id.action_list_to_detail, null, null, extras)

// In DetailFragment:
sharedElementEnterTransition = TransitionInflater
    .from(requireContext())
    .inflateTransition(android.R.transition.move)

// ImageView in detail layout must have the same transitionName

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

ภาพเคลื่อนไหวแบบสปริงให้ความรู้สึกเป็นธรรมชาติกว่าแบบเชิงเส้นหรือแบบชะลอ เพราะจำลองฟิสิกส์ของสปริงจริง:

implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'

// Spring animation on a button press:
val spring = SpringAnimation(binding.fabAdd, DynamicAnimation.SCALE_X, 1f).apply {
    spring = SpringForce(1f).apply {
        stiffness = SpringForce.STIFFNESS_MEDIUM
        dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY
    }
}

binding.fabAdd.setOnClickListener {
    binding.fabAdd.scaleX = 0.8f
    spring.start()
}

Lottie — ภาพเคลื่อนไหวที่ซับซ้อน

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

// app/build.gradle:
// implementation 'com.airbnb.android:lottie:6.4.0'

<!-- In layout XML -->
<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/lottieView"
    android:layout_width="200dp"
    android:layout_height="200dp"
    app:lottie_rawRes="@raw/loading_animation"
    app:lottie_autoPlay="true"
    app:lottie_loop="true" />

// Control in code:
binding.lottieView.playAnimation()
binding.lottieView.pauseAnimation()

แนวทางปฏิบัติที่ดีสำหรับภาพเคลื่อนไหว

แนวทางสำหรับภาพเคลื่อนไหวที่ลื่นไหลและเข้าถึงได้:

  • ใช้ระยะเวลา 150–300 มิลลิวินาทีสำหรับภาพเคลื่อนไหว UI ส่วนใหญ่
  • เคารพ AnimatorUtils.areAnimatorsEnabled() หรือ Settings.System.ANIMATOR_DURATION_SCALE เสมอ
  • ผู้ใช้ที่มีความผิดปกติของระบบการทรงตัวอาจปิดภาพเคลื่อนไหวได้ — ตรวจสอบการตั้งค่าการช่วยเหลือพิเศษ Reduce Motion
  • อย่าทำให้สิ่งที่ไม่จำเป็นต้องเคลื่อนไหวเคลื่อนไหว — น้อยแต่มาก
  • ทดสอบบนอุปกรณ์ประสิทธิภาพต่ำ (ภาพเคลื่อนไหวอาจทำให้เฟรมตก)

ตรวจสอบความเข้าใจอย่างรวดเร็ว

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

ทบทวน: ภาพเคลื่อนไหวและการเปลี่ยนฉาก

ทำให้แอปของคุณมีชีวิตชีวาด้วยแอนิเมชันที่ลื่นไหล:

  • view.animate() — ปรับความโปร่งใส การเลื่อนตำแหน่ง การย่อขยาย และการหมุนได้อย่างรวดเร็ว
  • ObjectAnimator — ใช้กับคุณสมบัติใดก็ได้และควบคุมรายละเอียดได้อย่างละเอียด
  • AnimatorSet — จัดการแอนิเมเตอร์หลายตัวให้ทำงานประสานกัน (พร้อมกัน/ต่อจากกัน)
  • TransitionManager.beginDelayedTransition() — สร้างแอนิเมชันให้การเปลี่ยนแปลงเลย์เอาต์โดยอัตโนมัติ
  • การเปลี่ยนผ่านองค์ประกอบร่วม — ทำให้การต่อเนื่องระหว่างหน้าจอเป็นไปอย่างราบรื่น
  • Lottie — แอนิเมชัน JSON ที่ซับซ้อนจาก After Effects

ถัดไป: Bottom Navigation และแท็บสำหรับแอปที่มีหลายส่วน

คำถามที่พบบ่อย

บทเรียน “ภาพเคลื่อนไหวและการเปลี่ยนผ่าน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ภาพเคลื่อนไหวและการเปลี่ยนผ่าน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 5 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ภาพเคลื่อนไหวและการเปลี่ยนผ่าน”

สร้างภาพเคลื่อนไหวให้มุมมองด้วย ViewPropertyAnimator, ObjectAnimator และ AnimatorSet เพิ่มการเปลี่ยนผ่านของแฟรกเมนต์ ภาพเคลื่อนไหวขององค์ประกอบร่วม และฟิสิกส์แบบสปริง คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 5 บทเรียน

บทเรียน “ภาพเคลื่อนไหวและการเปลี่ยนผ่าน” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม

ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. พื้นฐาน Material Design
  2. ธีมและสไตล์
  3. มุมมองที่กำหนดเอง
  4. ภาพเคลื่อนไหวและการเปลี่ยนผ่าน
  5. การนำทางด้านล่างและแท็บ
← กลับไปที่ Android Academy