RecyclerView horizontal scroll snap in center

android, android-recyclerview, horizontal-scrolling

Solution

With `LinearSnapHelper`, this is now very easy.

All you need to do is this:

SnapHelper helper = new LinearSnapHelper();
helper.attachToRecyclerView(recyclerView);

Update

Available since 25.1.0, `PagerSnapHelper` can help achieve `ViewPager` like effect. Use it as you would use the `LinearSnapHelper`.

Old workaround:

If you wish for it to behave akin to the `ViewPager`, try this instead:

LinearSnapHelper snapHelper = new LinearSnapHelper() {
    @Override
    public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
        View centerView = findSnapView(layoutManager);
        if (centerView == null) 
            return RecyclerView.NO_POSITION;

        int position = layoutManager.getPosition(centerView);
        int targetPosition = -1;
        if (layoutManager.canScrollHorizontally()) {
            if (velocityX < 0) {
                targetPosition = position - 1;
            } else {
                targetPosition = position + 1;
            }
        }

        if (layoutManager.canScrollVertically()) {
            if (velocityY < 0) {
                targetPosition = position - 1;
            } else {
                targetPosition = position + 1;
            }
        }

        final int firstItem = 0;
        final int lastItem = layoutManager.getItemCount() - 1;
        targetPosition = Math.min(lastItem, Math.max(targetPosition, firstItem));
        return targetPosition;
    }
};
snapHelper.attachToRecyclerView(recyclerView);

The implementation above just returns the position next to the current item (centered) based on the direction of the velocity, regardless of the magnitude.

The former one is a first party solution included in the Support Library version 24.2.0. Meaning you have to add this to your app module's `build.gradle` or update it.

compile "com.android.support:recyclerview-v7:24.2.0"

Problem

I'm trying to make a carousel-like view here using RecyclerView, I want the item to snap in the middle of the screen when scrolling, one item at a time. I've tried using `recyclerView.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING);` but the view is still scrolling smoothly, I've also tried to implement my own logic using scroll listener like so: ``` recyclerView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); Log.v("Offset ", recyclerView.getWidth() + ""); if (newState == 0) { try { recyclerView.smoothScrollToPosition(layoutManager.findLastVisibleItemPosition()); recyclerView.scrollBy(20,0); if (layoutManager.findLastVisibleItemPosition() >= recyclerView.getAdapter().getItemCount() - 1) { Beam refresh = new Beam(); refresh.execute(createUrl()); } } catch (Exception e) { e.printStackTrace(); } } ``` The swipe from right to left is working fine now, but not the other way around, what am I missing here ?

Original source