57

The RecyclerView.scrollToPosition() is extremely strange. for example, supposed a RecyclerView named "rv".

  1. if now item 10 is under the current RecyclerView, call rv.scrollToPosition(10), the RecyclerView will scroll item 10 to bottom.

  2. if now item 10 is in the current RecyclerView, call rv.scrollToPosition(10), there won't be any scrolling, nothing will be done.

  3. if now item 10 is on the top of the current RecyclerView, call rv.scrollToPosition(10), the RecyclerView will scroll item 10 to top.

To help understanding, look at this picture enter image description here

But what i need is that, whenever i call it, the RecyclerView will scroll the supposed position to the top of current view just like case 3. How to do that?

Angel Koh
  • 12,479
  • 7
  • 64
  • 91
cryyyyy
  • 619
  • 1
  • 6
  • 5
  • 4
    http://stackoverflow.com/questions/26875061/scroll-recyclerview-to-show-selected-item-on-top – USKMobility Oct 25 '15 at 10:57
  • 1
    That's exactly what i want ! thank u so much! ummm...i think i should delete my question... – cryyyyy Oct 25 '15 at 13:46
  • use linearLayoutManager.scrollToPositionWithOffset(2, 20); see [Scroll RecyclerView to show selected item on top](http://stackoverflow.com/questions/26875061/scroll-recyclerview-to-show-selected-item-on-top) – Fan Applelin Mar 02 '17 at 03:07
  • Possible duplicate of [Scroll RecyclerView to show selected item on top](https://stackoverflow.com/questions/26875061/scroll-recyclerview-to-show-selected-item-on-top) – Zeeshan May 02 '18 at 13:42
  • https://stackoverflow.com/questions/26875061/scroll-recyclerview-to-show-selected-item-on-top – razi Jun 13 '19 at 10:10
  • I made +1 in this question because of its presentation.it is good way to explain the problem. – Gaurav Bansal Aug 20 '20 at 10:22

5 Answers5

66

If I understand the question, you want to scroll to a specific position but that position is the adapter's position and not the RecyclerView's item position.

You can only achieve this through the LayoutManager.

Do something like:

rv.getLayoutManager().scrollToPosition(youPositionInTheAdapter).
yugidroid
  • 6,640
  • 2
  • 30
  • 45
  • How do I pass the AdapterPosition to this method? – Bot Jul 28 '16 at 07:34
  • 16
    I'm certain that this is incorrect. Calling scrollToPosition on the RecyclerView just calls the same method on the LayoutManager. It even says in the javadocs "RecyclerView does not implement scrolling logic, rather forwards the call to android.support.v7.widget.RecyclerView.LayoutManager#scrollToPosition Calling scrollToPosition on the RecyclerView or the LayoutManager will have the exact same effect. – Graydyn Young Oct 25 '17 at 14:30
  • @Zeeshan 's answer with the StaggeredGridLayoutManager greatly worked! (See below) – Abigail La'Fay Dec 05 '19 at 00:51
  • 1
    Use linearLayoutManager.scrollToPositionWithOffset(position, 0); – Capella Feb 19 '20 at 20:32
  • 2
    @Castor thanks for this. A seemingly minor, yet critical distinction - `scrollToPosition` appears to ensure the target view is visible somewhere in the recycler (often the bottom), while `scrollToPositionWithOffset` `0` ensures the target view is visible at the TOP of the recycler. – rmirabelle Mar 29 '21 at 20:00
28

Below link might solve your problem:

https://stackoverflow.com/a/43505830/4849554

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);
Luke
  • 7,110
  • 6
  • 45
  • 74
Ritesh
  • 1,030
  • 2
  • 12
  • 28
  • 4
    That's ok if you wan to do a smooth scroll, but what if you want to do an automatic scroll? – 4gus71n Jun 22 '17 at 16:01
  • If you want to automatic scroll down to some position, in that case this code will work perfect. it will scroll down automatic to some position with smooth transition...I hope I got your question right. – Ritesh Jun 23 '17 at 15:04
  • 4
    The thing is that my RecyclerView has like 700 items, so if the distance to the target scroll is < 30, then I use smooth scroll, and this code works perfectly. But if the distance to the target scroll is > 30 I want to automatically jump to that item. In that case I don't want to use smooth scroll. How can I "snap to start" that item? – 4gus71n Jun 26 '17 at 12:36
  • 1
    @4gus71n I have the same question. I believe that you want to change the action to use jumpTo() There used to be an instantaneous scroller but that was deprecated at api 22 – Alexander N. Aug 01 '17 at 21:47
  • 2
    @AlexanderN. Nice I didn't know about that method. Gonna try it ASAP. – 4gus71n Aug 03 '17 at 15:43
  • @Luke i did similar but i am getting this error java.lang.NullPointerException: Attempt to read from field 'androidx.recyclerview.widget.RecyclerView$ViewFlinger androidx.recyclerview.widget.RecyclerView.mViewFlinger' on a null object reference at androidx.recyclerview.widget.RecyclerView$SmoothScroller.start(RecyclerView.java:11795) at androidx.recyclerview.widget.RecyclerView$LayoutManager.startSmoothScroll(RecyclerView.java:8470) – Abhishek Apr 21 '20 at 18:51
5

This is the Kotlin code snippet but you can just get the point for scrolling to the item by position properly. The point is to declare the member variable for the layout manager and use its method to scroll.

lateinit var layoutManager: LinearLayoutManager

fun setupView() {
    ...

    layoutManager = LinearLayoutManager(applicationContext)
    mainRecyclerView.layoutManager = layoutManager

    ...
}

fun moveToPosition(position: Int) {
    layoutManager.scrollToPositionWithOffset(position, 0)
}
Capella
  • 881
  • 3
  • 19
  • 32
4

If you want to scroll to a specific position and that position is the adapter's position, then you can use StaggeredGridLayoutManager scrollToPosition

   StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
   staggeredGridLayoutManager.scrollToPosition(10);
   recyclerView.setLayoutManager(staggeredGridLayoutManager);
Zeeshan
  • 11,851
  • 21
  • 73
  • 98
0

try recycler_view.smoothScrollBy(0, 100); here 0 represents x-coordinate and 100 represents y-coordinate I used this in vertical recyclerView where I wanted to scroll to next position in the vertical list and for coming to the previous position I simply replaced 100 with -100

rajat singh
  • 165
  • 1
  • 11