Skip to main content
Android UI Design with Kotlin
CHAPTER 16 Beginner

Android UI Animations and Transitions

Updated: May 31, 2026
6 min read

# CHAPTER 16

Android UI Animations and Transitions

1. Introduction

If layout files are the skeleton of your app and colors are the skin, then animations are its heartbeat. Without motion, an app feels like a static PDF document. Motion provides feedback (a button compressing when clicked), guides focus (a new item sliding into a list), and creates delight. In this chapter, we will explore the different ways to animate Android UIs, from simple fades to the incredibly powerful MotionLayout.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the difference between View Animations and Property Animations.
  • Implement simple alpha (fade) and translation (slide) animations.
  • Use animateLayoutChanges for automatic UI transitions.
  • Understand the basics of MotionLayout for complex, interactive animations.
  • Add an animated loading state to a UI.

3. Property Animation Basics

The modern way to animate in Android is using ViewPropertyAnimator. It is incredibly simple and runs efficiently. Want to fade a view out over half a second?
kotlin
1234567
val myView = findViewById<ImageView>(R.id.heroImage)

// Fade out
myView.animate()
    .alpha(0f) // Target opacity (0 is invisible)
    .setDuration(500) // 500 milliseconds (half a second)
    .start()

You can chain multiple properties. Let's make a view move up and fade in simultaneously:

kotlin
123456789
myView.translationY = 100f // Start 100 pixels lower
myView.alpha = 0f // Start invisible

myView.animate()
    .translationY(0f) // Move to original position
    .alpha(1f) // Fade to fully visible
    .setDuration(600)
    .setInterpolator(DecelerateInterpolator()) // Slows down at the end
    .start()

4. Automatic Layout Transitions

Sometimes you just want a view to animate when you change its visibility (e.g., from GONE to VISIBLE), without writing manual animation code. Android can do this automatically! Just add this one line to the parent ViewGroup (like a LinearLayout or ConstraintLayout) in your XML:
xml
1
android:animateLayoutChanges="true"

Now, whenever you add, remove, or change the visibility of a child inside that layout, Android will automatically apply a smooth crossfade and slide animation.

5. Shared Element Transitions

When you click an item in a list (like an image) and it seamlessly expands to become the hero image on the next screen, that is a Shared Element Transition. It creates a strong visual connection between two screens. It involves giving the views on both screens the same transitionName and telling the OS to animate between them during the Activity or Fragment transaction.

6. The Power of MotionLayout

For highly complex, interactive animations—like a header that collapses and morphs as the user scrolls—standard animations fall short. MotionLayout is a subclass of ConstraintLayout designed specifically for building complex motion.

Instead of writing animation code in Kotlin, MotionLayout uses a separate XML file called a MotionScene. In the MotionScene, you define:

  1. 1. A ConstraintSet for the START state.
  1. 2. A ConstraintSet for the END state.
  1. 3. A Transition that defines how long it takes to morph from START to END, and whether it's triggered by a click or a user swiping (scrolling).

*Android Studio provides a visual Motion Editor to help build these without typing raw XML!*

7. Mini Project: Animated Onboarding UI

Let's add a "slide up and fade in" entrance animation to the Onboarding screen we built in Chapter 8.
kotlin
12345678910111213141516171819202122
class OnboardingActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_onboarding)

        val titleText = findViewById<TextView>(R.id.titleText)
        val descText = findViewById<TextView>(R.id.descText)
        val startButton = findViewById<Button>(R.id.startButton)

        // Initial states: Invisible and slightly pushed down
        val viewsToAnimate = listOf(titleText, descText, startButton)
        viewsToAnimate.forEach {
            it.alpha = 0f
            it.translationY = 50f
        }

        // Staggered Animation: Animate them one by one
        titleText.animate().alpha(1f).translationY(0f).setDuration(500).setStartDelay(300).start()
        descText.animate().alpha(1f).translationY(0f).setDuration(500).setStartDelay(500).start()
        startButton.animate().alpha(1f).translationY(0f).setDuration(500).setStartDelay(700).start()
    }
}

*This creates a beautiful, cascading entrance effect!*

8. Design Principles

  • Meaningful Motion: Don't animate things just because you can. Animation should explain logic (e.g., a card expanding into a detail view) or provide feedback (a button ripple).
  • Speed: Animations should be fast. If an animation takes 2 seconds, the user will get frustrated waiting for it. The sweet spot is usually between 200ms and 400ms.

9. Common Mistakes

  • Linear Interpolation: Using linear, constant-speed animations looks robotic. Physical objects in the real world accelerate and decelerate. Always use interpolators (like AccelerateDecelerateInterpolator or FastOutSlowInInterpolator) to make motion look natural.
  • Over-animating: Making text spin, bounce, and flash all at once. Less is more.

10. Best Practices

  • Use Lottie (a library by Airbnb) if you need highly complex vector animations (like a character waving or a complex loading spinner). Designers can create these in After Effects and export them as JSON, which Lottie renders perfectly in Android.

11. Exercises

  1. 1. Take a MaterialCardView and add a click listener. When clicked, use .animate() to scale its X and Y down to 0.9f (90% size) for 100ms, and then back to 1f. This creates a satisfying "squish" effect!
  1. 2. Add android:animateLayoutChanges="true" to a LinearLayout and toggle the visibility of a child view between VISIBLE and GONE.

12. UI Design Challenges

Challenge: Create a "Like" button animation. When the user taps a gray, hollow heart icon, animate its scale up to 1.5f, change its color resource to Red, and immediately animate the scale back down to 1.0f.

13. MCQ Quiz with Answers

Question 1

What is the easiest way to automatically animate views appearing and disappearing inside a ConstraintLayout?

Question 2

What is the primary purpose of an Interpolator in an animation?

14. Interview Questions

  • Q: Explain the difference between traditional View Animations (res/anim) and modern Property Animations (ViewPropertyAnimator).
  • Q: What is a Shared Element Transition and how does it improve UX?
  • Q: Briefly explain what a MotionScene file does when working with MotionLayout.

15. Summary

Motion breathes life into code. We learned how to use ViewPropertyAnimator to easily fade and move views programmatically, discovered the magic of animateLayoutChanges for automatic transitions, and touched upon the capabilities of MotionLayout for advanced interactions.

16. Next Chapter Recommendation

We have built screens, styled them, and animated them. But copying and pasting the same XML code across 10 screens is a nightmare. In Chapter 17: Custom UI Components and Reusable Design, we will learn how to build our own reusable custom views to keep our code DRY (Don't Repeat Yourself).

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·