Animations & Transitions
Animate views with ViewPropertyAnimator, ObjectAnimator, and AnimatorSet. Add fragment transitions, shared element animations, and spring physics.
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 speedAccelerateInterpolator— starts slow, speeds up (exits)DecelerateInterpolator— starts fast, slows down (entries)AccelerateDecelerateInterpolator— slow → fast → slow (default)OvershootInterpolator— overshoots the target and bounces backBounceInterpolator— 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 transitionNameSpring 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()orSettings.System.ANIMATOR_DURATION_SCALE - Users with vestibular disorders may disable animations — check
Reduce Motionaccessibility 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, rotationObjectAnimator— any property, fine-grained controlAnimatorSet— 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.
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
- Material Design Basics
- Themes & Styles
- Custom Views
- Animations & Transitions
- Bottom Navigation & Tabs