Does anyone know how to modify sensitivity of ViewPager?
Currently I use a ViewPager from android v4 support library to implement my own photo viewer.
However, default ViewPager is too sensitive, when my finger touch down on screen and moves by a very short distinct(maybe just 0.5cm). Then ViewPager will be toggled to scroll to next/previous photo view.
Is there any way to overwrite default behavior of ViewPager to decrease sensitivity?
Thanks to any response.
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.
While Pethő Jonatán has a good pointer to achieve better sensitivity, along with fling distance you may want to reduce minimumVelocity as well.
You may want to do this after initializing viewpager in onCreate:
viewPager = findViewById(R.id.viewPager);
Field mFlingDistance;
Field mMinimumVelocity;
try {
mFlingDistance=ViewPager.class.getDeclaredField("mFlingDistance");
mMinimumVelocity=ViewPager.class.getDeclaredField("mMinimumVelocity");
mFlingDistance.setAccessible(true);
mMinimumVelocity.setAccessible(true);
//customize the values
mFlingDistance.set(viewPager, 10);
mMinimumVelocity.set(viewPager, 400);
} catch (Exception e) {
e.printStackTrace();
}
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.
You can reflect the mFlingDistance field like this:
Field mFlingDistance;
mFlingDistance = ViewPager.class.getDeclaredField("mFlingDistance");
mFlingDistance.setAccessible(true);
// Set custom value:
mFlingDistance.set(mPager, 30);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With