I honestly didn't find a true mean to make Viewpager2 works with swiping events on left and right preview since Viewpager2 class is final. But things worked out very well with using NestedScrollview.
UPDATED NEW SOLUTION
Thanks to CmTiger Who provided a more optimized way for scrolling. I have tested it. You can play with the value LEFT_RIGHT = 300 for left to right scrolling. get value from dp to pixel. however, you like it. This new solution need optimization.
float last_x = 0;
nestedScrollView.setOnTouchListener(new View.OnTouchListener() {
int LEFT_RIGHT = -300; // your offsets
int RIGHT_LEFT = 300;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float x = motionEvent.getX();
if (x > last_x) {
motionEvent.offsetLocation(LEFT_RIGHT, 0);
} else {
motionEvent.offsetLocation(RIGHT_LEFT, 0);
}
last_x = x;
viewpager.dispatchTouchEvent(motionEvent);
return false;
}
});
OLD SOLUTION
<androidx.core.widget.NestedScrollView
android:id="@+id/nestedScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/_5sdp"
android:paddingStart="@dimen/_50sdp"
android:paddingEnd="@dimen/_50sdp"
/>
</androidx.core.widget.NestedScrollView>
Just use this code to make it work. Increase int value of speed to increase speed and vice versa.
nestedScroll = view.findViewById(R.id.nestedScroll);
nestedScroll2.setOnTouchListener(new View.OnTouchListener() {
float start = 0;
float limit_to_start_moving = 5;
int speed = 7;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
// Touch Starts X DOWN_X
start = motionEvent.getX();
}
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
// get position
float X2 = motionEvent.getX();
if ((X2 - limit_to_start_moving) > start) {
// LEFT & RIGHT DIRECTION
if (start < X2)
viewpager.fakeDragBy((motionEvent.getXPrecision() * speed));
else
viewpager.fakeDragBy((motionEvent.getXPrecision() * -speed));
start = X2; // old position
} else if ((X2 + limit_to_start_moving) < start) {
if (start < X2)
viewpager.fakeDragBy((motionEvent.getXPrecision() * speed));
else
viewpager.fakeDragBy((motionEvent.getXPrecision() * -speed));
start = X2;
}
}
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
if (viewpager.isFakeDragging()) {
viewpager.endFakeDrag();
}
}
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
if (viewpager.isFakeDragging()) {
viewpager.endFakeDrag();
if (start > motionEvent.getX()) {
viewpager.setCurrentItem(viewpager.getCurrentItem() + 1);
} else {
viewpager.setCurrentItem(viewpager.getCurrentItem() - 1);
}
}
}
return false;
}
});
viewpager.setOnTouchListener(new View.OnTouchListener() {
float lastValue;
float value;
float delta;
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
lastValue = event.getX();
viewpager.beginFakeDrag();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
value = event.getX();
delta = value - lastValue;
viewpager.fakeDragBy(delta * 2);
lastValue = value;
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
viewpager.endFakeDrag();
}
return false;
}
});