Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to calculate scroll-end position

I would like to know where the scroll (recyclerview, scrollview) will stop scrolling with velocity in Fling method. Is there any way to calculate this?

like image 871
Gintama Avatar asked Mar 15 '23 06:03

Gintama


1 Answers

I looked at the source code of RecyclerView and it uses an internal class ViewFlinger with the following member variable:

private ScrollerCompat mScroller;

To summarize, when a fling is detected it is handled by an instance of ViewFlinger. ViewFlinger then sets the fling velocity on mScroller and lets it figure out the animation curve. ScrollerCompat is what you want to get to b/c it has handy APIs for getting the final x and y of the scroll. Unfortunately the ScrollerCompat instance mScroller that you need to get to is not exposed by RecyclerView. mScroller.fling(0, 0, velocityX, velocityY, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE); Two possible solutions. Both should be done once you get the fling event and involve getting or creating a ScrollerCompat instance:

  1. Use reflection to grab the mScroller instance.
  2. Keep a ScrollerCompat instance and initialize it the same way as RecyclerView. Then pass in the fling velocity: mScroller.fling(0, 0, velocityX, velocityY, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);

Once you have the ScrollerCompat instance, call the public APIs to get the final x and y positions. Assuming that you have views that are all the same size and knowing your starting fling location within the list, you can calculate the view that it will land on. Something like this:

// Assumes vertical scrolling
const int childHeight = this.getChildren().getChildAt(0).getHeight();
float childOffset = mScroller.getFinalY() / childHeight;
like image 164
Trevor Carothers Avatar answered Mar 25 '23 07:03

Trevor Carothers