Android Academy · Lesson

Animations & Transitions

Animate views with ViewPropertyAnimator, ObjectAnimator, and AnimatorSet. Add fragment transitions, shared element animations, and spring physics.

Lesson 4 of 513 steps

Animations & Transitions is a free Android Academy lesson on CoddyKit. This is lesson 4 of 5. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, and your progress syncs across the web and the CoddyKit app. The Android Academy course includes 5 lessons in total.

Why Animations Matter

Animations make apps feel alive and responsive. They:

  • Provide visual feedback for user actions
  • Show how screens relate to each other
  • Make data changes less jarring
  • Help users understand what changed and why

The key rule: animations should serve the UI, not distract from it. Keep them under 300ms.

ViewPropertyAnimator — Quick Animations

The simplest way to animate a view. Chain calls and call 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 animates any property of any object by name. More flexible than 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 — Sequential & Parallel

AnimatorSet orchestrates multiple animators to run together or one after another:

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()
}

Interpolators

Interpolators control the rate of change of an animation. Common ones:

  • LinearInterpolator — constant speed
  • AccelerateInterpolator — starts slow, speeds up (exits)
  • DecelerateInterpolator — starts fast, slows down (entries)
  • AccelerateDecelerateInterpolator — slow → fast → slow (default)
  • OvershootInterpolator — overshoots the target and bounces back
  • BounceInterpolator — bounces at the end

TransitionManager — Layout Changes

Animate layout changes automatically by calling TransitionManager.beginDelayedTransition() before changing visibility or layout properties:

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 Transitions

Add enter/exit animations to fragment transactions:

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)

Shared Element Transitions

Share a view between two screens so it animates from one position to another (e.g., a thumbnail that expands into a full image):

// 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

Spring Animation

Spring animations feel more natural than linear or decelerate because they simulate physical spring physics:

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 — Complex Animations

Lottie plays After Effects animations exported as JSON. Perfect for loading spinners, onboarding, and empty states:

// 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()

Animation Best Practices

Guidelines for smooth, accessible animations:

  • Duration 150–300ms for most UI animations
  • Always respect AnimatorUtils.areAnimatorsEnabled() or Settings.System.ANIMATOR_DURATION_SCALE
  • Users with vestibular disorders may disable animations — check Reduce Motion accessibility setting
  • Don't animate things that don't need it — less is more
  • Test on low-end devices (animations can cause frame drops)

Quick Check

Which interpolator is best for an element entering the screen to feel like it decelerates and settles?

Recap: Animations & Transitions

Give your app life with smooth animations:

  • view.animate() — quick alpha, translation, scale, rotation
  • ObjectAnimator — any property, fine-grained control
  • AnimatorSet — orchestrate multiple animators (with/after)
  • TransitionManager.beginDelayedTransition() — auto-animate layout changes
  • Shared element transitions — seamless cross-screen continuity
  • Lottie — complex JSON animations from After Effects

Next: Bottom Navigation and Tabs for multi-section apps.

Free to start

Learn Kotlin with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
36
Lessons
152

Frequently Asked Questions

Is the “Animations & Transitions” lesson free?

Yes — any 3 lessons of the Android Academy learning path, including “Animations & Transitions”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Android Academy course includes 5 lessons in total.

What will I learn in “Animations & Transitions”?

Animate views with ViewPropertyAnimator, ObjectAnimator, and AnimatorSet. Add fragment transitions, shared element animations, and spring physics. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Android Academy?

No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 5.

How long does the “Animations & Transitions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Android Academy lesson?

Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Material Design Basics
  2. Themes & Styles
  3. Custom Views
  4. Animations & Transitions
  5. Bottom Navigation & Tabs
← Back to Android Academy