← All courses

RecyclerView & Lists

🗓 May 31, 2026 ⏱ 2 min read

Why RecyclerView?

Showing a list of 1,000 items by creating 1,000 views would freeze the app and run out of memory. RecyclerView solves this by keeping only the few rows visible on screen and recycling them as you scroll — when a row scrolls off the top, it’s reused for a new row at the bottom.

The four pieces

Data list Adapter ViewHolder Row XML
  • Data — your list of items.
  • Row layout — an XML file describing one row.
  • ViewHolder — holds references to a row’s views so they aren’t looked up repeatedly.
  • Adapter — creates ViewHolders and binds data to them.

A modern adapter with ListAdapter + DiffUtil

ListAdapter uses DiffUtil to figure out exactly what changed and animate it — no manual notifyDataSetChanged().

data class User(val id: Int, val name: String)

class UserAdapter : ListAdapter<User, UserAdapter.VH>(Diff) {
    object Diff : DiffUtil.ItemCallback<User>() {
        override fun areItemsTheSame(a: User, b: User) = a.id == b.id
        override fun areContentsTheSame(a: User, b: User) = a == b
    }
    class VH(val b: ItemUserBinding) : RecyclerView.ViewHolder(b.root)

    override fun onCreateViewHolder(parent: ViewGroup, type: Int): VH {
        val b = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return VH(b)
    }
    override fun onBindViewHolder(holder: VH, position: Int) {
        holder.b.name.text = getItem(position).name
    }
}

Wiring it up

val adapter = UserAdapter()
binding.recycler.layoutManager = LinearLayoutManager(this)
binding.recycler.adapter = adapter
adapter.submitList(listOf(User(1, "Anand"), User(2, "Priya")))

Handling clicks

Pass a lambda into the adapter and call it from onBindViewHolder — never give each row its own heavy listener logic.

Common mistakes

  • Calling notifyDataSetChanged() for everything — prefer submitList() with DiffUtil.
  • Forgetting to set a LayoutManager (the list shows nothing).
  • Doing image loading on the main thread inside onBindViewHolder — use a library like Coil.
Summary: RecyclerView recycles rows for performance. Use ListAdapter + DiffUtil + submitList() for clean, animated updates.