3

I've implemented drag to close and zoomable view in Fragment of a ViewPager. Now, it's swiping wasn't smooth because the touches of ViewPager and view in Fragment conflict with each other. So, i wrote a CustomViewPager class to override 'onInterceptTouchEvent' method so i can detect that if it is horizontal swipe and fragment view is not already zoomed or dragging then ViewPager should consume the touches to avoid conflicts and make the swipe smooth. But issue that i'm facing is that buttons click is also not getting actions as ViewPager doesn't pass touch to them and if I don't intercept the touch in ViewPager then ViewPager and fragment conflict. How can i allow clicks of childs but consume other events i.e. ACTION_MOVE until i want it to pass to childs.

CustomViewPager:

public class DemoViewPager extends ViewPager {
    private final int THRESHOLD = ScreenUtils.dpToPx(20);
    float diffX, diffY;
    private float initialXValue;
    private float initialYValue;
    private MotionEventListener motionEventListener;

    public DemoViewPager(@NonNull Context context) {
        super(context);
    }

    public DemoViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {


        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:

                initialXValue = ev.getX();
                initialYValue = ev.getY();

                return true;
//                break;
            case MotionEvent.ACTION_MOVE:

                diffX = ev.getX() - initialXValue;
                diffY = ev.getY() - initialYValue;


                boolean isHorizontalSwipe = Math.abs(diffY) < THRESHOLD;
                boolean isDraggable = motionEventListener != null && (motionEventListener.isDragging() || motionEventListener.isZoomed());


                if (!isHorizontalSwipe || isDraggable) {
                    return true;
                }

//                return true;
            break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:

                break;
            //return true;
        }

        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

       switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:

                initialXValue = ev.getX();
                initialYValue = ev.getY();

                if (motionEventListener != null)
                    motionEventListener.onMotionEventReceived(ev);

                break;
            case MotionEvent.ACTION_MOVE:

                diffX = ev.getX() - initialXValue;
                diffY = ev.getY() - initialYValue;

                boolean isHorizontalSwipe = Math.abs(diffY) < THRESHOLD;
                boolean isDraggable = motionEventListener != null && (motionEventListener.isDragging() || motionEventListener.isZoomed());


                if (!isHorizontalSwipe || isDraggable) {
                    if (motionEventListener != null)
                        motionEventListener.onMotionEventReceived(ev);

                    if (isDraggable)
                        return false;
                }

                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (motionEventListener != null)
                    motionEventListener.onMotionEventReceived(ev);

                break;
        }

        return super.onTouchEvent(ev);
    }

    public void setMotionEventListener(MotionEventListener motionEventListener) {
        this.motionEventListener = motionEventListener;
    }

    public interface MotionEventListener {
        void onMotionEventReceived(MotionEvent motionEvent);

        boolean isDragging();

        boolean isZoomed();
    }

}
Usman Rana
  • 2,067
  • 1
  • 21
  • 32

0 Answers0