RecyclerView Animation
Android Development
UI Animation
Kotlin Android
RecyclerView Programming

How to animate RecyclerView items when they appear

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Animating RecyclerView rows as they appear can make a list feel more polished, but it is easy to overdo it and end up with janky scrolling. The practical goal is to animate only the first appearance of a row or a controlled set of insertions, not every rebind that happens during normal scrolling.

Where the Animation Usually Belongs

The most common place to trigger an appearance animation is in onBindViewHolder. That is where the row view is available and its adapter position is known.

The important guard is to track the last animated position. Without that, the same cell may animate every time it is rebound, which feels broken.

kotlin
1class MessagesAdapter(
2    private val items: List<String>
3) : RecyclerView.Adapter<MessagesAdapter.MessageViewHolder>() {
4
5    private var lastAnimatedPosition = -1
6
7    class MessageViewHolder(val view: View) : RecyclerView.ViewHolder(view)
8
9    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
10        val view = LayoutInflater.from(parent.context)
11            .inflate(R.layout.row_message, parent, false)
12        return MessageViewHolder(view)
13    }
14
15    override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
16        holder.view.findViewById<TextView>(R.id.messageText).text = items[position]
17        animateIfNeeded(holder.itemView, position)
18    }
19
20    override fun getItemCount(): Int = items.size
21
22    private fun animateIfNeeded(view: View, position: Int) {
23        if (position <= lastAnimatedPosition) return
24
25        view.alpha = 0f
26        view.translationY = 40f
27        view.animate()
28            .alpha(1f)
29            .translationY(0f)
30            .setDuration(250)
31            .start()
32
33        lastAnimatedPosition = position
34    }
35}

This creates a simple fade-and-rise effect for newly appearing items.

When ItemAnimator Is a Better Fit

If you want to animate insertions, removals, or moves that come from dataset changes, use the RecyclerView.ItemAnimator mechanism. The default animator already handles many of those cases.

kotlin
1recyclerView.itemAnimator = DefaultItemAnimator().apply {
2    addDuration = 180
3    removeDuration = 180
4    moveDuration = 180
5    changeDuration = 120
6}

That is different from an entrance animation on first bind. ItemAnimator reacts to adapter change events. A bind-time animation reacts to visual appearance.

Avoid Re-Animating on Scroll

RecyclerView reuses item views aggressively. That is good for performance, but it means old visual state can leak into new rows unless you reset it.

If you add custom animation code, always set starting properties before the animation begins. In the example above, alpha and translationY are assigned explicitly before calling animate(). Without that reset, recycled views may appear halfway through an old animation state.

If you use ListAdapter and DiffUtil, the most stable pattern is often:

  1. Let DiffUtil compute structural changes.
  2. Use ItemAnimator for inserts and moves.
  3. Reserve manual bind-time animations for one-time entrance effects.

Performance Guidance

Animations are cheap only when they are simple. alpha, translationX, and translationY are good choices because they are GPU-friendly. Repeated layout passes or heavy shadow work are more expensive.

Also be careful with staggered animations across dozens of rows. They may look good in a demo and feel slow in real usage. Lists are primarily for reading and scanning, so the animation should support that instead of delaying it.

Common Pitfalls

  • Animating every bind instead of only the first visible appearance or a controlled insertion event.
  • Forgetting to reset alpha, translation, or scale before starting a new animation on a recycled view.
  • Using entrance animation logic when ItemAnimator is the correct tool for dataset changes.
  • Applying long durations that make fast scrolling feel sluggish.
  • Animating too many expensive properties instead of sticking to simple transforms.

Summary

  • A simple appearance animation usually lives in onBindViewHolder with a guard against repeat animations.
  • 'ItemAnimator is better for add, remove, move, and change events.'
  • Reset animated properties on recycled views so state does not leak between rows.
  • Prefer lightweight property animations such as alpha and translationY.
  • Good list animation should be subtle enough that it improves the UI without slowing it down.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.