Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwanted bounce effect on RecyclerView with SnapHelper

I am using a RecyclerView with a Horizontal LinearLayoutManager.

recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,false));

For the adapter items to snap at the center, I've attached a LinearSnapHelper to the recyclerview.

SnapHelper helper = new LinearSnapHelper();

helper.attachToRecyclerView(recyclerView);

Now, I have two scenarios where I would want an item to come to center

  1. When my activity launches, it should launch with a specific item snapped to center.
  2. On tapping on an item in the recyclerview, it should get centered. For this, I've overridden the OnClick method in adapter's ViewHolder.

For both scenarios, I'm using

recyclerView.smoothScrollToPosition(position);

and the item gets centered. This however happens with a bouncy animation where a little extra scroll happens first and post that the item bounces back.

How can I disable this bouncy animation to get a smooth scroll?

Things I've tried - Used below APIs in place of smoothScrollToPosition

  1. LinearLayoutManager.scrollToPosition()
  2. LinearLayoutManager.scrollToPositionWithOffset()

Both the above APIs don't give a smooth scroll, plus the item doesn't get centered properly (since it's difficult to figure out the correct offset value for items that are not yet created/recycled back during the API call)

I couldn't find any method to disable/override animations in RecyclerView's Documentation. Could someone please help..

like image 547
rush Avatar asked Sep 17 '17 11:09

rush


1 Answers

The solution is to use extended LinearLayoutManager:

import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;

public class NoBounceLinearLayoutManager extends LinearLayoutManager {

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

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, final int position) {
        LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
            @Override
            protected int getHorizontalSnapPreference() {
                return position > findFirstVisibleItemPosition() ? SNAP_TO_START : SNAP_TO_END;
            }
        };
        linearSmoothScroller.setTargetPosition(position);
        startSmoothScroll(linearSmoothScroller);
    }
}
like image 90
Andrew Vovk Avatar answered Oct 29 '22 17:10

Andrew Vovk