I have a ViewPager so inside this view pager I have different fragments so in first fragment I have a TouchImageView which contain 360 degree rotatable image. When I'm swiping left or right for the Touchimageview so back viewpager event also triggering means viewpager is scrolling so I want to disable viewpager touch event for this imageview area.
Eg: ViewPager -> Fragment -> TouchImageView
I have gone through several answers about disable to onInterceptTouchEvent() and onTouchEvent() based on need but its disabled complete view of the fragment.
Any help would be greatly appreciated!
ViewPager.java
public class MyCardViewPager extends ViewPager {
private boolean isScrollingEnabled = true;
public MyCardViewPager(@Nonnull Context context, @Nonnull AttributeSet attrs) {
super(context, attrs);
}
public MyCardViewPager(@NonNull Context context) {
super(context);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isScrollingEnabled) {
return super.onInterceptTouchEvent(ev);
}
return false;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isScrollingEnabled) {
return super.onTouchEvent(ev);
}
return false;
}
public void enableScroll(boolean enable) {
isScrollingEnabled = enable;
}
}
Fragment.java
@Override
public View onCreateView(@Nonnull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
myCardViewPager = new MyCardViewPager(context);
myCardViewPager.enableScroll(false);
imageViewSwipeListener();
}
private void imageViewSwipeListener() {
position = 18;
objectList();
imageview.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {
@Override
public void onSwipeRight() {
super.onSwipeRight();
position += 1;
if (position == 36) {
position = 0;
}
imageview.setImageResource(objectList.get(position));
}
@Override
public void onSwipeLeft() {
super.onSwipeLeft();
position -= 1;
if (position == -1) {
position = 35;
}
imageview.setImageResource(objectList.get(position));
}
});
}
OnSwipeTouchListener class
open class OnSwipeTouchListener(ctx: Context) : View.OnTouchListener {
private val gestureDetector: GestureDetector
companion object {
private val SWIPE_THRESHOLD = 100
private val SWIPE_VELOCITY_THRESHOLD = 100
}
init {
gestureDetector = GestureDetector(ctx, GestureListener())
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
return gestureDetector.onTouchEvent(event)
}
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
override fun onDown(e: MotionEvent): Boolean {
return true
}
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
var result = false
try {
val diffY = e2.y - e1.y
val diffX = e2.x - e1.x
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight()
} else {
onSwipeLeft()
}
result = true
}
} else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom()
} else {
onSwipeTop()
}
result = true
}
} catch (exception: Exception) {
exception.printStackTrace()
}
return result
}
}
open fun onSwipeRight() {}
open fun onSwipeLeft() {}
open fun onSwipeTop() {}
open fun onSwipeBottom() {}
}
first line in this method is just passing every
MotionEvent motionEventto sameView, which is default behavior without setting custom touch listener. BUTonTouchEventmethod returns boolean indicating that thisViewconsumed passed event. if defaultonTouchEventreturnsfalsethen same event is passed toviews parent, if it also wont consume it then, again, is passed up in hierarchy until some of parentingViews (ViewGroups) willreturn trueconfirming it can handle this event.your
imageviewis probably some custom/lib class, which occasionally (always?)return falseallowing to dispatch touch events up in hierarchy toViewPager, which can handle this touch andreturn true. thats why in above snippetonTouchmethod is returningtruealways when touch occurs onimageview- this touch is still passed to thisView, but even if it isn't handledreturn trueprevents dispatching same event up to parents