RecyclerView - How to smooth scroll to top of item on a certain position?

RecyclerView is designed to be extensible, so there is no need to subclass the LayoutManager (as droidev suggested) just to perform the scrolling.

Instead, just create a SmoothScroller with the preference SNAP_TO_START:

RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
  @Override protected int getVerticalSnapPreference() {
    return LinearSmoothScroller.SNAP_TO_START;
  }
};

Now you set the position where you want to scroll to:

smoothScroller.setTargetPosition(position);

and pass that SmoothScroller to the LayoutManager:

layoutManager.startSmoothScroll(smoothScroller);

for this you have to create a custom LayoutManager

public class LinearLayoutManagerWithSmoothScroller extends LinearLayoutManager {

    public LinearLayoutManagerWithSmoothScroller(Context context) {
        super(context, VERTICAL, false);
    }

    public LinearLayoutManagerWithSmoothScroller(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                                       int position) {
        RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private class TopSnappedSmoothScroller extends LinearSmoothScroller {
        public TopSnappedSmoothScroller(Context context) {
            super(context);

        }

        @Override
        public PointF computeScrollVectorForPosition(int targetPosition) {
            return LinearLayoutManagerWithSmoothScroller.this
                    .computeScrollVectorForPosition(targetPosition);
        }

        @Override
        protected int getVerticalSnapPreference() {
            return SNAP_TO_START;
        }
    }
}

use this for your RecyclerView and call smoothScrollToPosition.

example :

 recyclerView.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(context));
 recyclerView.smoothScrollToPosition(position);

this will scroll to top of the RecyclerView item of specified position.

hope this helps.


This is an extension function I wrote in Kotlin to use with the RecyclerView (based on @Paul Woitaschek answer):

fun RecyclerView.smoothSnapToPosition(position: Int, snapMode: Int = LinearSmoothScroller.SNAP_TO_START) {
  val smoothScroller = object : LinearSmoothScroller(this.context) {
    override fun getVerticalSnapPreference(): Int = snapMode
    override fun getHorizontalSnapPreference(): Int = snapMode
  }
  smoothScroller.targetPosition = position
  layoutManager?.startSmoothScroll(smoothScroller)
}

Use it like this:

myRecyclerView.smoothSnapToPosition(itemPosition)

We can try like this

    recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,new RecyclerView.State(), recyclerView.getAdapter().getItemCount());

Override the calculateDyToMakeVisible/calculateDxToMakeVisible function in LinearSmoothScroller to implement the offset Y/X position

override fun calculateDyToMakeVisible(view: View, snapPreference: Int): Int {
    return super.calculateDyToMakeVisible(view, snapPreference) - ConvertUtils.dp2px(10f)
}