android.support.v4.view.GestureDetectorCompat.java Source code

Java tutorial

Introduction

Here is the source code for android.support.v4.view.GestureDetectorCompat.java

Source

package android.support.v4.view;

import android.content.Context;
import android.os.Build.VERSION;
import android.os.Handler;
import android.os.Message;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import com.olacabs.customer.p076d.br;
import com.olacabs.customer.utils.Constants;
import com.sothree.slidinguppanel.p086a.R.R;

public class GestureDetectorCompat {
    private final GestureDetectorCompatImpl mImpl;

    interface GestureDetectorCompatImpl {
        boolean isLongpressEnabled();

        boolean onTouchEvent(MotionEvent motionEvent);

        void setIsLongpressEnabled(boolean z);

        void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener);
    }

    static class GestureDetectorCompatImplBase implements GestureDetectorCompatImpl {
        private static final int DOUBLE_TAP_TIMEOUT;
        private static final int LONGPRESS_TIMEOUT;
        private static final int LONG_PRESS = 2;
        private static final int SHOW_PRESS = 1;
        private static final int TAP = 3;
        private static final int TAP_TIMEOUT;
        private boolean mAlwaysInBiggerTapRegion;
        private boolean mAlwaysInTapRegion;
        private MotionEvent mCurrentDownEvent;
        private boolean mDeferConfirmSingleTap;
        private OnDoubleTapListener mDoubleTapListener;
        private int mDoubleTapSlopSquare;
        private float mDownFocusX;
        private float mDownFocusY;
        private final Handler mHandler;
        private boolean mInLongPress;
        private boolean mIsDoubleTapping;
        private boolean mIsLongpressEnabled;
        private float mLastFocusX;
        private float mLastFocusY;
        private final OnGestureListener mListener;
        private int mMaximumFlingVelocity;
        private int mMinimumFlingVelocity;
        private MotionEvent mPreviousUpEvent;
        private boolean mStillDown;
        private int mTouchSlopSquare;
        private VelocityTracker mVelocityTracker;

        private class GestureHandler extends Handler {
            GestureHandler() {
            }

            GestureHandler(Handler handler) {
                super(handler.getLooper());
            }

            public void handleMessage(Message message) {
                switch (message.what) {
                case GestureDetectorCompatImplBase.SHOW_PRESS /*1*/:
                    GestureDetectorCompatImplBase.this.mListener
                            .onShowPress(GestureDetectorCompatImplBase.this.mCurrentDownEvent);
                case GestureDetectorCompatImplBase.LONG_PRESS /*2*/:
                    GestureDetectorCompatImplBase.this.dispatchLongPress();
                case GestureDetectorCompatImplBase.TAP /*3*/:
                    if (GestureDetectorCompatImplBase.this.mDoubleTapListener == null) {
                        return;
                    }
                    if (GestureDetectorCompatImplBase.this.mStillDown) {
                        GestureDetectorCompatImplBase.this.mDeferConfirmSingleTap = true;
                    } else {
                        GestureDetectorCompatImplBase.this.mDoubleTapListener
                                .onSingleTapConfirmed(GestureDetectorCompatImplBase.this.mCurrentDownEvent);
                    }
                default:
                    throw new RuntimeException("Unknown message " + message);
                }
            }
        }

        static {
            LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
            TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
            DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
        }

        public GestureDetectorCompatImplBase(Context context, OnGestureListener onGestureListener,
                Handler handler) {
            if (handler != null) {
                this.mHandler = new GestureHandler(handler);
            } else {
                this.mHandler = new GestureHandler();
            }
            this.mListener = onGestureListener;
            if (onGestureListener instanceof OnDoubleTapListener) {
                setOnDoubleTapListener((OnDoubleTapListener) onGestureListener);
            }
            init(context);
        }

        private void init(Context context) {
            if (context == null) {
                throw new IllegalArgumentException("Context must not be null");
            } else if (this.mListener == null) {
                throw new IllegalArgumentException("OnGestureListener must not be null");
            } else {
                this.mIsLongpressEnabled = true;
                ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
                int scaledTouchSlop = viewConfiguration.getScaledTouchSlop();
                int scaledDoubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
                this.mMinimumFlingVelocity = viewConfiguration.getScaledMinimumFlingVelocity();
                this.mMaximumFlingVelocity = viewConfiguration.getScaledMaximumFlingVelocity();
                this.mTouchSlopSquare = scaledTouchSlop * scaledTouchSlop;
                this.mDoubleTapSlopSquare = scaledDoubleTapSlop * scaledDoubleTapSlop;
            }
        }

        public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) {
            this.mDoubleTapListener = onDoubleTapListener;
        }

        public void setIsLongpressEnabled(boolean z) {
            this.mIsLongpressEnabled = z;
        }

        public boolean isLongpressEnabled() {
            return this.mIsLongpressEnabled;
        }

        public boolean onTouchEvent(MotionEvent motionEvent) {
            int i;
            int action = motionEvent.getAction();
            if (this.mVelocityTracker == null) {
                this.mVelocityTracker = VelocityTracker.obtain();
            }
            this.mVelocityTracker.addMovement(motionEvent);
            boolean z = (action & MotionEventCompat.ACTION_MASK) == 6;
            int actionIndex = z ? MotionEventCompat.getActionIndex(motionEvent) : -1;
            int pointerCount = MotionEventCompat.getPointerCount(motionEvent);
            float f = 0.0f;
            float f2 = 0.0f;
            for (i = LONGPRESS_TIMEOUT; i < pointerCount; i += SHOW_PRESS) {
                if (actionIndex != i) {
                    f2 += MotionEventCompat.getX(motionEvent, i);
                    f += MotionEventCompat.getY(motionEvent, i);
                }
            }
            actionIndex = z ? pointerCount - 1 : pointerCount;
            f2 /= (float) actionIndex;
            f /= (float) actionIndex;
            boolean hasMessages;
            float yVelocity;
            float xVelocity;
            switch (action & MotionEventCompat.ACTION_MASK) {
            case LONGPRESS_TIMEOUT:
                if (this.mDoubleTapListener != null) {
                    hasMessages = this.mHandler.hasMessages(TAP);
                    if (hasMessages) {
                        this.mHandler.removeMessages(TAP);
                    }
                    if (this.mCurrentDownEvent == null || this.mPreviousUpEvent == null || !hasMessages
                            || !isConsideredDoubleTap(this.mCurrentDownEvent, this.mPreviousUpEvent, motionEvent)) {
                        this.mHandler.sendEmptyMessageDelayed(TAP, (long) DOUBLE_TAP_TIMEOUT);
                    } else {
                        this.mIsDoubleTapping = true;
                        actionIndex = (this.mDoubleTapListener.onDoubleTap(this.mCurrentDownEvent)
                                | LONGPRESS_TIMEOUT) | this.mDoubleTapListener.onDoubleTapEvent(motionEvent);
                        this.mLastFocusX = f2;
                        this.mDownFocusX = f2;
                        this.mLastFocusY = f;
                        this.mDownFocusY = f;
                        if (this.mCurrentDownEvent != null) {
                            this.mCurrentDownEvent.recycle();
                        }
                        this.mCurrentDownEvent = MotionEvent.obtain(motionEvent);
                        this.mAlwaysInTapRegion = true;
                        this.mAlwaysInBiggerTapRegion = true;
                        this.mStillDown = true;
                        this.mInLongPress = false;
                        this.mDeferConfirmSingleTap = false;
                        if (this.mIsLongpressEnabled) {
                            this.mHandler.removeMessages(LONG_PRESS);
                            this.mHandler.sendEmptyMessageAtTime(LONG_PRESS,
                                    (this.mCurrentDownEvent.getDownTime() + ((long) TAP_TIMEOUT))
                                            + ((long) LONGPRESS_TIMEOUT));
                        }
                        this.mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                                this.mCurrentDownEvent.getDownTime() + ((long) TAP_TIMEOUT));
                        return actionIndex | this.mListener.onDown(motionEvent);
                    }
                }
                actionIndex = LONGPRESS_TIMEOUT;
                this.mLastFocusX = f2;
                this.mDownFocusX = f2;
                this.mLastFocusY = f;
                this.mDownFocusY = f;
                if (this.mCurrentDownEvent != null) {
                    this.mCurrentDownEvent.recycle();
                }
                this.mCurrentDownEvent = MotionEvent.obtain(motionEvent);
                this.mAlwaysInTapRegion = true;
                this.mAlwaysInBiggerTapRegion = true;
                this.mStillDown = true;
                this.mInLongPress = false;
                this.mDeferConfirmSingleTap = false;
                if (this.mIsLongpressEnabled) {
                    this.mHandler.removeMessages(LONG_PRESS);
                    this.mHandler.sendEmptyMessageAtTime(LONG_PRESS,
                            (this.mCurrentDownEvent.getDownTime() + ((long) TAP_TIMEOUT))
                                    + ((long) LONGPRESS_TIMEOUT));
                }
                this.mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                        this.mCurrentDownEvent.getDownTime() + ((long) TAP_TIMEOUT));
                return actionIndex | this.mListener.onDown(motionEvent);
            case SHOW_PRESS /*1*/:
                this.mStillDown = false;
                MotionEvent obtain = MotionEvent.obtain(motionEvent);
                if (this.mIsDoubleTapping) {
                    hasMessages = this.mDoubleTapListener.onDoubleTapEvent(motionEvent) | LONGPRESS_TIMEOUT;
                } else if (this.mInLongPress) {
                    this.mHandler.removeMessages(TAP);
                    this.mInLongPress = false;
                    hasMessages = LONGPRESS_TIMEOUT;
                } else if (this.mAlwaysInTapRegion) {
                    hasMessages = this.mListener.onSingleTapUp(motionEvent);
                    if (this.mDeferConfirmSingleTap && this.mDoubleTapListener != null) {
                        this.mDoubleTapListener.onSingleTapConfirmed(motionEvent);
                    }
                } else {
                    VelocityTracker velocityTracker = this.mVelocityTracker;
                    int pointerId = MotionEventCompat.getPointerId(motionEvent, LONGPRESS_TIMEOUT);
                    velocityTracker.computeCurrentVelocity(Constants.MILLIS_IN_A_SECOND,
                            (float) this.mMaximumFlingVelocity);
                    yVelocity = VelocityTrackerCompat.getYVelocity(velocityTracker, pointerId);
                    xVelocity = VelocityTrackerCompat.getXVelocity(velocityTracker, pointerId);
                    hasMessages = (Math.abs(yVelocity) > ((float) this.mMinimumFlingVelocity)
                            || Math.abs(xVelocity) > ((float) this.mMinimumFlingVelocity))
                                    ? this.mListener.onFling(this.mCurrentDownEvent, motionEvent, xVelocity,
                                            yVelocity)
                                    : LONGPRESS_TIMEOUT;
                }
                if (this.mPreviousUpEvent != null) {
                    this.mPreviousUpEvent.recycle();
                }
                this.mPreviousUpEvent = obtain;
                if (this.mVelocityTracker != null) {
                    this.mVelocityTracker.recycle();
                    this.mVelocityTracker = null;
                }
                this.mIsDoubleTapping = false;
                this.mDeferConfirmSingleTap = false;
                this.mHandler.removeMessages(SHOW_PRESS);
                this.mHandler.removeMessages(LONG_PRESS);
                return hasMessages;
            case LONG_PRESS /*2*/:
                if (this.mInLongPress) {
                    return false;
                }
                xVelocity = this.mLastFocusX - f2;
                yVelocity = this.mLastFocusY - f;
                if (this.mIsDoubleTapping) {
                    return false | this.mDoubleTapListener.onDoubleTapEvent(motionEvent);
                }
                if (this.mAlwaysInTapRegion) {
                    i = (int) (f2 - this.mDownFocusX);
                    int i2 = (int) (f - this.mDownFocusY);
                    i = (i * i) + (i2 * i2);
                    if (i > this.mTouchSlopSquare) {
                        hasMessages = this.mListener.onScroll(this.mCurrentDownEvent, motionEvent, xVelocity,
                                yVelocity);
                        this.mLastFocusX = f2;
                        this.mLastFocusY = f;
                        this.mAlwaysInTapRegion = false;
                        this.mHandler.removeMessages(TAP);
                        this.mHandler.removeMessages(SHOW_PRESS);
                        this.mHandler.removeMessages(LONG_PRESS);
                    } else {
                        hasMessages = false;
                    }
                    if (i > this.mTouchSlopSquare) {
                        this.mAlwaysInBiggerTapRegion = false;
                    }
                    return hasMessages;
                } else if (Math.abs(xVelocity) < br.DEFAULT_BACKOFF_MULT
                        && Math.abs(yVelocity) < br.DEFAULT_BACKOFF_MULT) {
                    return false;
                } else {
                    boolean onScroll = this.mListener.onScroll(this.mCurrentDownEvent, motionEvent, xVelocity,
                            yVelocity);
                    this.mLastFocusX = f2;
                    this.mLastFocusY = f;
                    return onScroll;
                }
            case TAP /*3*/:
                cancel();
                return false;
            case R.SlidingUpPanelLayout_umanoDragView /*5*/:
                this.mLastFocusX = f2;
                this.mDownFocusX = f2;
                this.mLastFocusY = f;
                this.mDownFocusY = f;
                cancelTaps();
                return false;
            case R.SlidingUpPanelLayout_umanoOverlay /*6*/:
                this.mLastFocusX = f2;
                this.mDownFocusX = f2;
                this.mLastFocusY = f;
                this.mDownFocusY = f;
                this.mVelocityTracker.computeCurrentVelocity(Constants.MILLIS_IN_A_SECOND,
                        (float) this.mMaximumFlingVelocity);
                int actionIndex2 = MotionEventCompat.getActionIndex(motionEvent);
                actionIndex = MotionEventCompat.getPointerId(motionEvent, actionIndex2);
                f2 = VelocityTrackerCompat.getXVelocity(this.mVelocityTracker, actionIndex);
                float yVelocity2 = VelocityTrackerCompat.getYVelocity(this.mVelocityTracker, actionIndex);
                for (actionIndex = LONGPRESS_TIMEOUT; actionIndex < pointerCount; actionIndex += SHOW_PRESS) {
                    if (actionIndex != actionIndex2) {
                        int pointerId2 = MotionEventCompat.getPointerId(motionEvent, actionIndex);
                        if ((VelocityTrackerCompat.getYVelocity(this.mVelocityTracker, pointerId2) * yVelocity2)
                                + (VelocityTrackerCompat.getXVelocity(this.mVelocityTracker, pointerId2)
                                        * f2) < 0.0f) {
                            this.mVelocityTracker.clear();
                            return false;
                        }
                    }
                }
                return false;
            default:
                return false;
            }
        }

        private void cancel() {
            this.mHandler.removeMessages(SHOW_PRESS);
            this.mHandler.removeMessages(LONG_PRESS);
            this.mHandler.removeMessages(TAP);
            this.mVelocityTracker.recycle();
            this.mVelocityTracker = null;
            this.mIsDoubleTapping = false;
            this.mStillDown = false;
            this.mAlwaysInTapRegion = false;
            this.mAlwaysInBiggerTapRegion = false;
            this.mDeferConfirmSingleTap = false;
            if (this.mInLongPress) {
                this.mInLongPress = false;
            }
        }

        private void cancelTaps() {
            this.mHandler.removeMessages(SHOW_PRESS);
            this.mHandler.removeMessages(LONG_PRESS);
            this.mHandler.removeMessages(TAP);
            this.mIsDoubleTapping = false;
            this.mAlwaysInTapRegion = false;
            this.mAlwaysInBiggerTapRegion = false;
            this.mDeferConfirmSingleTap = false;
            if (this.mInLongPress) {
                this.mInLongPress = false;
            }
        }

        private boolean isConsideredDoubleTap(MotionEvent motionEvent, MotionEvent motionEvent2,
                MotionEvent motionEvent3) {
            if (!this.mAlwaysInBiggerTapRegion
                    || motionEvent3.getEventTime() - motionEvent2.getEventTime() > ((long) DOUBLE_TAP_TIMEOUT)) {
                return false;
            }
            int x = ((int) motionEvent.getX()) - ((int) motionEvent3.getX());
            int y = ((int) motionEvent.getY()) - ((int) motionEvent3.getY());
            if ((x * x) + (y * y) < this.mDoubleTapSlopSquare) {
                return true;
            }
            return false;
        }

        private void dispatchLongPress() {
            this.mHandler.removeMessages(TAP);
            this.mDeferConfirmSingleTap = false;
            this.mInLongPress = true;
            this.mListener.onLongPress(this.mCurrentDownEvent);
        }
    }

    static class GestureDetectorCompatImplJellybeanMr2 implements GestureDetectorCompatImpl {
        private final GestureDetector mDetector;

        public GestureDetectorCompatImplJellybeanMr2(Context context, OnGestureListener onGestureListener,
                Handler handler) {
            this.mDetector = new GestureDetector(context, onGestureListener, handler);
        }

        public boolean isLongpressEnabled() {
            return this.mDetector.isLongpressEnabled();
        }

        public boolean onTouchEvent(MotionEvent motionEvent) {
            return this.mDetector.onTouchEvent(motionEvent);
        }

        public void setIsLongpressEnabled(boolean z) {
            this.mDetector.setIsLongpressEnabled(z);
        }

        public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) {
            this.mDetector.setOnDoubleTapListener(onDoubleTapListener);
        }
    }

    public GestureDetectorCompat(Context context, OnGestureListener onGestureListener) {
        this(context, onGestureListener, null);
    }

    public GestureDetectorCompat(Context context, OnGestureListener onGestureListener, Handler handler) {
        if (VERSION.SDK_INT > 17) {
            this.mImpl = new GestureDetectorCompatImplJellybeanMr2(context, onGestureListener, handler);
        } else {
            this.mImpl = new GestureDetectorCompatImplBase(context, onGestureListener, handler);
        }
    }

    public boolean isLongpressEnabled() {
        return this.mImpl.isLongpressEnabled();
    }

    public boolean onTouchEvent(MotionEvent motionEvent) {
        return this.mImpl.onTouchEvent(motionEvent);
    }

    public void setIsLongpressEnabled(boolean z) {
        this.mImpl.setIsLongpressEnabled(z);
    }

    public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) {
        this.mImpl.setOnDoubleTapListener(onDoubleTapListener);
    }
}