How to build a horizontal ListView with RecyclerView
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
On modern Android, a horizontal list is built with RecyclerView, not the old ListView widget. The key is a horizontal LinearLayoutManager, but a good solution also handles spacing, item updates, and recycled view state correctly. If you only flip the orientation and ignore the rest, the list works at first and then becomes hard to maintain.
Configure the RecyclerView
The baseline setup is small: give the view a layout manager, an adapter, and fixed sizing if item height is stable.
That gives you horizontal scrolling immediately.
A Simple Adapter
This is enough for a working prototype. For frequently changing data, move to ListAdapter plus DiffUtil so updates stay efficient.
Add Spacing the Right Way
Horizontal rows usually need spacing between items. Do that with ItemDecoration instead of hardcoding margins into every layout.
Then attach it:
This keeps spacing logic separate from view binding.
Keep UI State Out of Recycled Views
A classic RecyclerView bug is storing selected state only in the clicked view. When the holder is recycled, the wrong item appears selected.
Track selection in adapter state or in the backing model, then rebind from that state in onBindViewHolder. That is the correct mental model for RecyclerView: views are temporary, data state is authoritative.
Plan for Real Data Updates
Many horizontal lists start as static mock data and then become live content rails. When that happens, switch to ListAdapter plus DiffUtil instead of calling notifyDataSetChanged() for every refresh. Diff-based updates keep animations smooth and preserve scroll position more reliably, which matters a lot in horizontal carousels where a jarring reset is obvious immediately.
Layout XML Matters Too
A clean container layout helps the horizontal list feel intentional.
For card rails, consistent item width usually produces smoother scrolling. Uneven widths are valid, but they should be a deliberate design choice.
If the row displays remote images, pair the adapter with Glide or Coil so image decoding and caching do not block horizontal scrolling.
Common Pitfalls
- Forgetting to set
LinearLayoutManager.HORIZONTAL, leaving the list vertical. - Using
notifyDataSetChangedfor every update instead of diff-based updates. - Putting spacing into every item layout instead of using
ItemDecoration. - Storing interaction state only in the view holder and then fighting recycled-state bugs.
Summary
- Use
RecyclerViewwith a horizontalLinearLayoutManagerfor modern horizontal lists. - Start with a simple adapter, then use
DiffUtilwhen data updates matter. - Add spacing with
ItemDecorationinstead of scattered layout margins. - Keep selection and other UI state in data, not only in recycled views.
- Treat
RecyclerViewas a reusable rendering system, not as a manual row container.

