The best solution i got was to use gestureDetector.SimpleOnGestureListener
inside on recyclerView.addOnItemTouchListener(this)
.
Step-1: In OnCreate()
method. The GestureListener
class is created on Step-3.
gestureDetector = new GestureDetector(getActivity(), new GestureListener());
Step-2: Call recyclerView.addOnItemTouchListener()
method.
recyclerView.addOnItemTouchListener(this);
Step-3: Create class GestureListener
which extend GestureDetector.SimpleOnGestureListener
.
public class GestureListener extends GestureDetector.SimpleOnGestureListener {
private final int Y_BUFFER = 10;
@Override
public boolean onDown(MotionEvent e) {
// Prevent ViewPager from intercepting touch events as soon as a DOWN is detected.
// If we don't do this the next MOVE event may trigger the ViewPager to switch
// tabs before this view can intercept the event.
Log.d("vp", "true1");
recyclerView.getParent().requestDisallowInterceptTouchEvent(true);
return super.onDown(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (Math.abs(distanceX) > Math.abs(distanceY)) {
Log.d("vp2", "true");
// Detected a horizontal scroll, allow the viewpager from switching tabs
recyclerView.getParent().requestDisallowInterceptTouchEvent(false);
} else if (Math.abs(distanceY) > Y_BUFFER) {
// Detected a vertical scroll prevent the viewpager from switching tabs
Log.d("vp3", "false");
recyclerView.getParent().requestDisallowInterceptTouchEvent(true);
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
Step-4: Call gestureDetector.onTouchEvent(e)
from onInterceptTouchEvent()
.
@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
gestureDetector.onTouchEvent(e);
return false;
}
UPDATE
Kotlin Version
This is the kotlin version of the previous answer.
val gestureDetector = GestureDetector(requireActivity(), object: GestureDetector.SimpleOnGestureListener() {
override fun onDown(e: MotionEvent?): Boolean {
rv.parent.requestDisallowInterceptTouchEvent(true)
return super.onDown(e)
}
override fun onScroll(
e1: MotionEvent?,
e2: MotionEvent?,
distanceX: Float,
distanceY: Float
): Boolean {
if (abs(distanceX) > abs(distanceY)) {
rv.parent.requestDisallowInterceptTouchEvent(false)
} else if (abs(distanceY) > 10) {
rv.parent.requestDisallowInterceptTouchEvent(true)
}
return super.onScroll(e1, e2, distanceX, distanceY)
}
})
rv.addOnItemTouchListener(object: RecyclerView.OnItemTouchListener {
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
gestureDetector.onTouchEvent(e)
return false
}
})