How to modify sensitivity of viewpager?
For ViewPager2
extract and increase mTouchSlop
using reflection.
private fun ViewPager2.reduceDragSensitivity() {
val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView")
recyclerViewField.isAccessible = true
val recyclerView = recyclerViewField.get(this) as RecyclerView
val touchSlopField = RecyclerView::class.java.getDeclaredField("mTouchSlop")
touchSlopField.isAccessible = true
val touchSlop = touchSlopField.get(recyclerView) as Int
touchSlopField.set(recyclerView, touchSlop*8) // "8" was obtained experimentally
}
Call this function from your view pager
val viewPager: ViewPager2 = view.findViewById(R.id.pager)
viewPager.reduceDragSensitivity()
Java version
private void reduceDragSensitivity() {
try {
Field ff = ViewPager2.class.getDeclaredField("mRecyclerView") ;
ff.setAccessible(true);
RecyclerView recyclerView = (RecyclerView) ff.get(viewPager);
Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop") ;
touchSlopField.setAccessible(true);
int touchSlop = (int) touchSlopField.get(recyclerView);
touchSlopField.set(recyclerView,touchSlop*4);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
All credits to Alexander Shevelev and Mahmoud Shabat.
I've checked out ViewPager.java from src of compatibility library and seems there's not way to do it by xml or some setter. ViewPager has code like the following:
final float density = context.getResources().getDisplayMetrics().density;
mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);
mCloseEnough = (int) (CLOSE_ENOUGH * density);
mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density);
As You can see, it uses it's internal constants for determination of fling distance and etc.
Good news are: You can copy ViewPager (here licence of it should be considered) to Your code and extend it e.g. to get fling distance from xml attribute.