RecyclerView smoothScrollBy over scrolls the content with on fling gesture

4.3k Views Asked by At

Every time fling gesture is detected in Recycler View, I would like to smooth scroll right a value, usually it's a width of recycler view (getWidth of RecyclerView).

The problem is that fling is usually detected with onTouchEvent which "drags" the view by amount of px and then makes the gesture (smoothScrollBy) which means that view is overscrolled by amount of px.

I tried to detect what's the value of those px but ACTION_DOWN does not seem to be called so I am having a hard time doing that.

I know about "smoothScrollToPosition", the problem is that every item might have a different width.

How can I figure out how to smoothScroll every time on fling gesture without getting additional px?

Thanks

@Override
public boolean fling(int velocityX, int velocityY) {
    Logger.d(TAG, "Fling");

    isFirstOnTouchEvent = true;

    Logger.d(TAG, "firstX: " + firstX + " lastX: " + lastX);
    Logger.d(TAG, "diff? " + (firstX - lastX));

    if(velocityX > 0) {
        smoothScrollBy(getWidth() - (int) (firstX - lastX), 0);
    } else {
        smoothScrollBy(-getWidth(), 0);
    }

    Logger.d(TAG, "\n\n\n");

    return true;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
    return super.onInterceptTouchEvent(e);
}

private boolean isFirstOnTouchEvent = true;
private double firstX;
private double lastX;

@Override
public boolean onTouchEvent(MotionEvent e) {
    Logger.d(TAG, "e: " + e.getAction() + " with raw x: " + e.getRawX() + " with x: " + e.getX());

    if(isFirstOnTouchEvent) {
        isFirstOnTouchEvent = false;

        firstX = e.getX();
    }

    lastX = e.getX();

    return super.onTouchEvent(e);
}
1

There are 1 best solutions below

0
On

Here's a simpler hack for smooth scrolling to a certain position on a fling event:

@Override
public boolean fling(int velocityX, int velocityY) {

    smoothScrollToPosition(position);
    return super.fling(0, 0);
}

Override the fling method with a call to smoothScrollToPosition(int position), where "int position" is the position of the view you want in the adapter. You will need to get the value of the position somehow, but that's dependent on your needs and implementation.