Scroll RecyclerView to show selected item on top
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When a user selects an item in a RecyclerView, a common UI requirement is to scroll that item into view and align it with the top of the list. The most reliable way to do that with a vertical list is usually LinearLayoutManager.scrollToPositionWithOffset, optionally wrapped in post so the scroll runs after layout has happened.
Why scrollToPosition is not enough
RecyclerView.scrollToPosition(position) makes sure the item is visible, but it does not guarantee that the item will land at the top. The layout manager is free to place it anywhere that satisfies visibility.
If you specifically want top alignment, you need an API that also accepts an offset. For a vertical LinearLayoutManager, that method is scrollToPositionWithOffset(position, 0).
Basic Kotlin example
Here is the standard pattern:
An offset of 0 means "place the item flush with the top edge."
Run the scroll after layout if needed
If you trigger the scroll too early, the RecyclerView may not have finished its layout pass yet. In that case, post the work:
This is especially helpful when the data set has just changed, the adapter has just been attached, or you are restoring selection after navigation.
Handling user selection through the adapter
In many apps, the selection starts in the adapter or fragment. A simple flow looks like this:
If the selected item should also be visually highlighted, update the adapter state first and then scroll so the top-aligned row is already rendered in its selected style.
Decorations, padding, and restored state
The exact visual result can change if the list uses top padding or an item decoration. In those cases, an offset of 0 aligns the row with the start of the padded content area, not necessarily the very top pixel of the screen. If you want a gap above the selected row, pass a positive offset instead of changing the scroll method.
State restoration matters too. If you reopen the screen and want the previously selected item on top again, restore the selection and then perform the offset scroll after the adapter data is available. Doing it in the opposite order often leads to no-op scrolls. This matters most when the list is repopulated asynchronously from a ViewModel or database query. In practice, many "scroll did nothing" bugs come from timing, not from the scroll method itself.
Common Pitfalls
- Using
scrollToPositionand expecting top alignment. - Triggering the scroll before the
RecyclerViewhas finished layout. - Forgetting to validate the selected position against the adapter item count.
- Assuming every layout manager supports
scrollToPositionWithOffset; that method is specific to layout managers such asLinearLayoutManager.
Summary
- Use
LinearLayoutManager.scrollToPositionWithOffset(position, 0)when the selected row must appear at the top. - Wrap the call in
recyclerView.postif the list has not finished layout yet. - '
scrollToPositiononly guarantees visibility, not top alignment.' - Account for padding, decorations, and state restoration when the final placement must be exact.

