I have a simple activity which has a root layout.The root layout contains a recyclerview. Recyclerview will contain 20 items created from items.xml , which consists of 3 text views.Here items.xml represent single item in the recyclerview.
The recycler view can be scrolled both the ways , it is kind a loop of the items between 1 to 20.
I have a requirement to smoothscroll only 4 items , irrespective of the velocity of the swipe/fling.
Approaches which i have tried many approaches but coudn't succeed till now. If anyone can give any suggestions , that would be very helpful.
SnapHelper - this seems to snap only the item which is in the center.
Using gesture detector - the gestures are getting detected for all the actions , but i am unable to prevent the recyclerview's default scrolling behaviour.
The main issue is the over-scrolling of recycler view due to varing velocities of user scrolls and flings.
Here is my set up for the gesture detector.
public myRecyclerTouchListner(final Context context, final RecyclerView recycleView,
final LinearLayoutManager linearLayoutManager,
final ClickListener clicklistener){
final ViewConfiguration vc = ViewConfiguration.get(context);
final int swipeMinDistance = vc.getScaledPagingTouchSlop();
final int swipeThresholdVelocity = vc.getScaledMinimumFlingVelocity();
final int swipeMaxOffPath = vc.getScaledTouchSlop();
this.clicklistener=clicklistener;
simpleGestureDetector =new GestureDetector(context,new GestureDetector.SimpleOnGestureListener( ){
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d("try", "on Fling called");
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE &&
Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//From Right to Left
recycleView.smoothScrollToPosition(linearLayoutManager.
findLastCompletelyVisibleItemPosition() + Constants.spanLength);
return true;
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE &&
Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
//From Left to Right
recycleView.smoothScrollToPosition(linearLayoutManager.
findFirstCompletelyVisibleItemPosition() - Constants.spanLength);
return true;
}
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
Log.d("Try", "Long press gesture");
View child=recycleView.findChildViewUnder(e.getX(),e.getY());
if(child!=null && clicklistener!=null){
clicklistener.onLongClick(child,recycleView.getChildAdapterPosition(child));
}
}
});
It turns out I had to use Snaphelper for custom scroll behavior in case wherein I need control over programmatic scroll and user-scroll(fling).
This was exactly what I was looking for: How to snap RecyclerView items so that every X items would be considered like a single unit to snap to?
I hope it will be helpful :)