From 4054bd6d6c5d51d9492184b1881253c223ddbf7d Mon Sep 17 00:00:00 2001 From: Paul Westbrook Date: Thu, 20 Sep 2012 16:55:04 -0700 Subject: Use gesture detector from support lib Bug: 7206080 Change-Id: I9b5d332d095335f13b61c9c9ccd8152a462a9eb5 --- .../android/ex/photo/views/GestureDetector.java | 656 --------------------- .../src/com/android/ex/photo/views/PhotoView.java | 22 +- 2 files changed, 8 insertions(+), 670 deletions(-) delete mode 100644 photoviewer/src/com/android/ex/photo/views/GestureDetector.java (limited to 'photoviewer') diff --git a/photoviewer/src/com/android/ex/photo/views/GestureDetector.java b/photoviewer/src/com/android/ex/photo/views/GestureDetector.java deleted file mode 100644 index c117661..0000000 --- a/photoviewer/src/com/android/ex/photo/views/GestureDetector.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ex.photo.views; - -import android.content.Context; -import android.os.Handler; -import android.os.Message; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; - -/** - * Detects various gestures and events using the supplied {@link MotionEvent}s. - * The {@link OnGestureListener} callback will notify users when a particular - * motion event has occurred. This class should only be used with {@link MotionEvent}s - * reported via touch (don't use for trackball events). - * - * To use this class: - * - */ -public class GestureDetector { - /** - * The listener that is used to notify when gestures occur. - * If you want to listen for all the different gestures then implement - * this interface. If you only want to listen for a subset it might - * be easier to extend {@link SimpleOnGestureListener}. - */ - public interface OnGestureListener { - - /** - * Notified when a tap occurs with the down {@link MotionEvent} - * that triggered it. This will be triggered immediately for - * every down event. All other events should be preceded by this. - * - * @param e The down motion event. - */ - boolean onDown(MotionEvent e); - - /** - * The user has performed a down {@link MotionEvent} and not performed - * a move or up yet. This event is commonly used to provide visual - * feedback to the user to let them know that their action has been - * recognized i.e. highlight an element. - * - * @param e The down motion event - */ - void onShowPress(MotionEvent e); - - /** - * Notified when a tap occurs with the up {@link MotionEvent} - * that triggered it. - * - * @param e The up motion event that completed the first tap - * @return true if the event is consumed, else false - */ - boolean onSingleTapUp(MotionEvent e); - - /** - * Notified when a scroll occurs with the initial on down {@link MotionEvent} and the - * current move {@link MotionEvent}. The distance in x and y is also supplied for - * convenience. - * - * @param e1 The first down motion event that started the scrolling. - * @param e2 The move motion event that triggered the current onScroll. - * @param distanceX The distance along the X axis that has been scrolled since the last - * call to onScroll. This is NOT the distance between {@code e1} - * and {@code e2}. - * @param distanceY The distance along the Y axis that has been scrolled since the last - * call to onScroll. This is NOT the distance between {@code e1} - * and {@code e2}. - * @return true if the event is consumed, else false - */ - boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY); - - /** - * Notified when a long press occurs with the initial on down {@link MotionEvent} - * that trigged it. - * - * @param e The initial on down motion event that started the longpress. - */ - void onLongPress(MotionEvent e); - - /** - * Notified of a fling event when it occurs with the initial on down {@link MotionEvent} - * and the matching up {@link MotionEvent}. The calculated velocity is supplied along - * the x and y axis in pixels per second. - * - * @param e1 The first down motion event that started the fling. - * @param e2 The move motion event that triggered the current onFling. - * @param velocityX The velocity of this fling measured in pixels per second - * along the x axis. - * @param velocityY The velocity of this fling measured in pixels per second - * along the y axis. - * @return true if the event is consumed, else false - */ - boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); - } - - /** - * The listener that is used to notify when a double-tap or a confirmed - * single-tap occur. - */ - public interface OnDoubleTapListener { - /** - * Notified when a single-tap occurs. - *

- * Unlike {@link OnGestureListener#onSingleTapUp(MotionEvent)}, this - * will only be called after the detector is confident that the user's - * first tap is not followed by a second tap leading to a double-tap - * gesture. - * - * @param e The down motion event of the single-tap. - * @return true if the event is consumed, else false - */ - boolean onSingleTapConfirmed(MotionEvent e); - - /** - * Notified when a double-tap occurs. - * - * @param e The down motion event of the first tap of the double-tap. - * @return true if the event is consumed, else false - */ - boolean onDoubleTap(MotionEvent e); - - /** - * Notified when an event within a double-tap gesture occurs, including - * the down, move, and up events. - * - * @param e The motion event that occurred during the double-tap gesture. - * @return true if the event is consumed, else false - */ - boolean onDoubleTapEvent(MotionEvent e); - } - - /** - * A convenience class to extend when you only want to listen for a subset - * of all the gestures. This implements all methods in the - * {@link OnGestureListener} and {@link OnDoubleTapListener} but does - * nothing and return {@code false} for all applicable methods. - */ - public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener { - public boolean onSingleTapUp(MotionEvent e) { - return false; - } - - public void onLongPress(MotionEvent e) { - } - - public boolean onScroll(MotionEvent e1, MotionEvent e2, - float distanceX, float distanceY) { - return false; - } - - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, - float velocityY) { - return false; - } - - public void onShowPress(MotionEvent e) { - } - - public boolean onDown(MotionEvent e) { - return false; - } - - public boolean onDoubleTap(MotionEvent e) { - return false; - } - - public boolean onDoubleTapEvent(MotionEvent e) { - return false; - } - - public boolean onSingleTapConfirmed(MotionEvent e) { - return false; - } - } - - private int mTouchSlopSquare; - private int mDoubleTapTouchSlopSquare; - private int mDoubleTapSlopSquare; - private int mMinimumFlingVelocity; - private int mMaximumFlingVelocity; - - private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout(); - private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout(); - private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout(); - - // constants for Message.what used by GestureHandler below - private static final int SHOW_PRESS = 1; - private static final int LONG_PRESS = 2; - private static final int TAP = 3; - - private final Handler mHandler; - private final OnGestureListener mListener; - private OnDoubleTapListener mDoubleTapListener; - - private boolean mStillDown; - private boolean mInLongPress; - private boolean mAlwaysInTapRegion; - private boolean mAlwaysInBiggerTapRegion; - - private MotionEvent mCurrentDownEvent; - private MotionEvent mPreviousUpEvent; - - /** - * True when the user is still touching for the second tap (down, move, and - * up events). Can only be true if there is a double tap listener attached. - */ - private boolean mIsDoubleTapping; - - private float mLastFocusX; - private float mLastFocusY; - private float mDownFocusX; - private float mDownFocusY; - - private boolean mIsLongpressEnabled; - - /** - * Determines speed during touch scrolling - */ - private VelocityTracker mVelocityTracker; - - private class GestureHandler extends Handler { - GestureHandler() { - super(); - } - - GestureHandler(Handler handler) { - super(handler.getLooper()); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case SHOW_PRESS: - mListener.onShowPress(mCurrentDownEvent); - break; - - case LONG_PRESS: - dispatchLongPress(); - break; - - case TAP: - // If the user's finger is still down, do not count it as a tap - if (mDoubleTapListener != null && !mStillDown) { - mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent); - } - break; - - default: - throw new RuntimeException("Unknown message " + msg); //never - } - } - } - - /** - * Creates a GestureDetector with the supplied listener. - * This variant of the constructor should be used from a non-UI thread - * (as it allows specifying the Handler). - * - * @param listener the listener invoked for all the callbacks, this must - * not be null. - * @param handler the handler to use - * - * @throws NullPointerException if either {@code listener} or - * {@code handler} is null. - * - * @deprecated Use {@link #GestureDetector(android.content.Context, - * android.view.GestureDetector.OnGestureListener, android.os.Handler)} instead. - */ - @Deprecated - public GestureDetector(OnGestureListener listener, Handler handler) { - this(null, listener, handler); - } - - /** - * Creates a GestureDetector with the supplied listener. - * You may only use this constructor from a UI thread (this is the usual situation). - * @see android.os.Handler#Handler() - * - * @param listener the listener invoked for all the callbacks, this must - * not be null. - * - * @throws NullPointerException if {@code listener} is null. - * - * @deprecated Use {@link #GestureDetector(android.content.Context, - * android.view.GestureDetector.OnGestureListener)} instead. - */ - @Deprecated - public GestureDetector(OnGestureListener listener) { - this(null, listener, null); - } - - /** - * Creates a GestureDetector with the supplied listener. - * You may only use this constructor from a UI thread (this is the usual situation). - * @see android.os.Handler#Handler() - * - * @param context the application's context - * @param listener the listener invoked for all the callbacks, this must - * not be null. - * - * @throws NullPointerException if {@code listener} is null. - */ - public GestureDetector(Context context, OnGestureListener listener) { - this(context, listener, null); - } - - /** - * Creates a GestureDetector with the supplied listener. - * You may only use this constructor from a UI thread (this is the usual situation). - * @see android.os.Handler#Handler() - * - * @param context the application's context - * @param listener the listener invoked for all the callbacks, this must - * not be null. - * @param handler the handler to use - * - * @throws NullPointerException if {@code listener} is null. - */ - public GestureDetector(Context context, OnGestureListener listener, Handler handler) { - if (handler != null) { - mHandler = new GestureHandler(handler); - } else { - mHandler = new GestureHandler(); - } - mListener = listener; - if (listener instanceof OnDoubleTapListener) { - setOnDoubleTapListener((OnDoubleTapListener) listener); - } - init(context); - } - - /** - * Creates a GestureDetector with the supplied listener. - * You may only use this constructor from a UI thread (this is the usual situation). - * @see android.os.Handler#Handler() - * - * @param context the application's context - * @param listener the listener invoked for all the callbacks, this must - * not be null. - * @param handler the handler to use - * - * @throws NullPointerException if {@code listener} is null. - */ - public GestureDetector(Context context, OnGestureListener listener, Handler handler, - boolean unused) { - this(context, listener, handler); - } - - private void init(Context context) { - if (mListener == null) { - throw new NullPointerException("OnGestureListener must not be null"); - } - mIsLongpressEnabled = true; - - // Fallback to support pre-donuts releases - int touchSlop, doubleTapSlop, doubleTapTouchSlop; - final ViewConfiguration configuration = ViewConfiguration.get(context); - touchSlop = configuration.getScaledTouchSlop(); - doubleTapTouchSlop = configuration.getScaledTouchSlop(); - doubleTapSlop = configuration.getScaledDoubleTapSlop(); - mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity(); - mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity(); - mTouchSlopSquare = touchSlop * touchSlop; - mDoubleTapTouchSlopSquare = doubleTapTouchSlop * doubleTapTouchSlop; - mDoubleTapSlopSquare = doubleTapSlop * doubleTapSlop; - } - - /** - * Sets the listener which will be called for double-tap and related - * gestures. - * - * @param onDoubleTapListener the listener invoked for all the callbacks, or - * null to stop listening for double-tap gestures. - */ - public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) { - mDoubleTapListener = onDoubleTapListener; - } - - /** - * Set whether longpress is enabled, if this is enabled when a user - * presses and holds down you get a longpress event and nothing further. - * If it's disabled the user can press and hold down and then later - * moved their finger and you will get scroll events. By default - * longpress is enabled. - * - * @param isLongpressEnabled whether longpress should be enabled. - */ - public void setIsLongpressEnabled(boolean isLongpressEnabled) { - mIsLongpressEnabled = isLongpressEnabled; - } - - /** - * @return true if longpress is enabled, else false. - */ - public boolean isLongpressEnabled() { - return mIsLongpressEnabled; - } - - /** - * Analyzes the given motion event and if applicable triggers the - * appropriate callbacks on the {@link OnGestureListener} supplied. - * - * @param ev The current motion event. - * @return true if the {@link OnGestureListener} consumed the event, - * else false. - */ - public boolean onTouchEvent(MotionEvent ev) { - final int action = ev.getAction(); - - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - mVelocityTracker.addMovement(ev); - - final boolean pointerUp = - (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP; - final int skipIndex = pointerUp ? ev.getActionIndex() : -1; - - // Determine focal point - float sumX = 0, sumY = 0; - final int count = ev.getPointerCount(); - for (int i = 0; i < count; i++) { - if (skipIndex == i) continue; - sumX += ev.getX(i); - sumY += ev.getY(i); - } - final int div = pointerUp ? count - 1 : count; - final float focusX = sumX / div; - final float focusY = sumY / div; - - boolean handled = false; - - switch (action & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_POINTER_DOWN: - mDownFocusX = mLastFocusX = focusX; - mDownFocusY = mLastFocusY = focusY; - // Cancel long press and taps - cancelTaps(); - break; - - case MotionEvent.ACTION_POINTER_UP: - mDownFocusX = mLastFocusX = focusX; - mDownFocusY = mLastFocusY = focusY; - - // Check the dot product of current velocities. - // If the pointer that left was opposing another velocity vector, clear. - mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); - final int upIndex = ev.getActionIndex(); - final int id1 = ev.getPointerId(upIndex); - final float x1 = mVelocityTracker.getXVelocity(id1); - final float y1 = mVelocityTracker.getYVelocity(id1); - for (int i = 0; i < count; i++) { - if (i == upIndex) continue; - - final int id2 = ev.getPointerId(i); - final float x = x1 * mVelocityTracker.getXVelocity(id2); - final float y = y1 * mVelocityTracker.getYVelocity(id2); - - final float dot = x + y; - if (dot < 0) { - mVelocityTracker.clear(); - break; - } - } - break; - - case MotionEvent.ACTION_DOWN: - if (mDoubleTapListener != null) { - boolean hadTapMessage = mHandler.hasMessages(TAP); - if (hadTapMessage) mHandler.removeMessages(TAP); - if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage && - isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) { - // This is a second tap - mIsDoubleTapping = true; - // Give a callback with the first tap of the double-tap - handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent); - // Give a callback with down event of the double-tap - handled |= mDoubleTapListener.onDoubleTapEvent(ev); - } else { - // This is a first tap - mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT); - } - } - - mDownFocusX = mLastFocusX = focusX; - mDownFocusY = mLastFocusY = focusY; - if (mCurrentDownEvent != null) { - mCurrentDownEvent.recycle(); - } - mCurrentDownEvent = MotionEvent.obtain(ev); - mAlwaysInTapRegion = true; - mAlwaysInBiggerTapRegion = true; - mStillDown = true; - mInLongPress = false; - - if (mIsLongpressEnabled) { - mHandler.removeMessages(LONG_PRESS); - mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() - + TAP_TIMEOUT + LONGPRESS_TIMEOUT); - } - mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT); - handled |= mListener.onDown(ev); - break; - - case MotionEvent.ACTION_MOVE: - if (mInLongPress) { - break; - } - final float scrollX = mLastFocusX - focusX; - final float scrollY = mLastFocusY - focusY; - if (mIsDoubleTapping) { - // Give the move events of the double-tap - handled |= mDoubleTapListener.onDoubleTapEvent(ev); - } else if (mAlwaysInTapRegion) { - final int deltaX = (int) (focusX - mDownFocusX); - final int deltaY = (int) (focusY - mDownFocusY); - int distance = (deltaX * deltaX) + (deltaY * deltaY); - if (distance > mTouchSlopSquare) { - handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); - mLastFocusX = focusX; - mLastFocusY = focusY; - mAlwaysInTapRegion = false; - mHandler.removeMessages(TAP); - mHandler.removeMessages(SHOW_PRESS); - mHandler.removeMessages(LONG_PRESS); - } - if (distance > mDoubleTapTouchSlopSquare) { - mAlwaysInBiggerTapRegion = false; - } - } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) { - handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); - mLastFocusX = focusX; - mLastFocusY = focusY; - } - break; - - case MotionEvent.ACTION_UP: - mStillDown = false; - MotionEvent currentUpEvent = MotionEvent.obtain(ev); - if (mIsDoubleTapping) { - // Finally, give the up event of the double-tap - handled |= mDoubleTapListener.onDoubleTapEvent(ev); - } else if (mInLongPress) { - mHandler.removeMessages(TAP); - mInLongPress = false; - } else if (mAlwaysInTapRegion) { - handled = mListener.onSingleTapUp(ev); - } else { - - // A fling must travel the minimum tap distance - final VelocityTracker velocityTracker = mVelocityTracker; - final int pointerId = ev.getPointerId(0); - velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); - final float velocityY = velocityTracker.getYVelocity(pointerId); - final float velocityX = velocityTracker.getXVelocity(pointerId); - - if ((Math.abs(velocityY) > mMinimumFlingVelocity) - || (Math.abs(velocityX) > mMinimumFlingVelocity)){ - handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY); - } - } - if (mPreviousUpEvent != null) { - mPreviousUpEvent.recycle(); - } - // Hold the event we obtained above - listeners may have changed the original. - mPreviousUpEvent = currentUpEvent; - if (mVelocityTracker != null) { - // This may have been cleared when we called out to the - // application above. - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - mIsDoubleTapping = false; - mHandler.removeMessages(SHOW_PRESS); - mHandler.removeMessages(LONG_PRESS); - break; - - case MotionEvent.ACTION_CANCEL: - cancel(); - break; - } - - return handled; - } - - private void cancel() { - mHandler.removeMessages(SHOW_PRESS); - mHandler.removeMessages(LONG_PRESS); - mHandler.removeMessages(TAP); - mVelocityTracker.recycle(); - mVelocityTracker = null; - mIsDoubleTapping = false; - mStillDown = false; - mAlwaysInTapRegion = false; - mAlwaysInBiggerTapRegion = false; - if (mInLongPress) { - mInLongPress = false; - } - } - - private void cancelTaps() { - mHandler.removeMessages(SHOW_PRESS); - mHandler.removeMessages(LONG_PRESS); - mHandler.removeMessages(TAP); - mIsDoubleTapping = false; - mAlwaysInTapRegion = false; - mAlwaysInBiggerTapRegion = false; - if (mInLongPress) { - mInLongPress = false; - } - } - - private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp, - MotionEvent secondDown) { - if (!mAlwaysInBiggerTapRegion) { - return false; - } - - if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) { - return false; - } - - int deltaX = (int) firstDown.getX() - (int) secondDown.getX(); - int deltaY = (int) firstDown.getY() - (int) secondDown.getY(); - return (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare); - } - - private void dispatchLongPress() { - mHandler.removeMessages(TAP); - mInLongPress = true; - mListener.onLongPress(mCurrentDownEvent); - } -} diff --git a/photoviewer/src/com/android/ex/photo/views/PhotoView.java b/photoviewer/src/com/android/ex/photo/views/PhotoView.java index 4dd0a08..8575bb1 100644 --- a/photoviewer/src/com/android/ex/photo/views/PhotoView.java +++ b/photoviewer/src/com/android/ex/photo/views/PhotoView.java @@ -28,7 +28,10 @@ import android.graphics.Paint.Style; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; +import android.support.v4.view.GestureDetectorCompat; import android.util.AttributeSet; +import android.view.GestureDetector.OnGestureListener; +import android.view.GestureDetector.OnDoubleTapListener; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; @@ -39,8 +42,8 @@ import com.android.ex.photo.fragments.PhotoViewFragment.HorizontallyScrollable; /** * Layout for the photo list view header. */ -public class PhotoView extends View implements GestureDetector.OnGestureListener, - GestureDetector.OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener, +public class PhotoView extends View implements OnGestureListener, + OnDoubleTapListener, ScaleGestureDetector.OnScaleGestureListener, HorizontallyScrollable { /** Zoom animation duration; in milliseconds */ private final static long ZOOM_ANIMATION_DURATION = 300L; @@ -107,7 +110,7 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener private int mCropSize; /** Gesture detector */ - private GestureDetector mGestureDetector; + private GestureDetectorCompat mGestureDetector; /** Gesture detector that detects pinch gestures */ private ScaleGestureDetector mScaleGetureDetector; /** An external click listener */ @@ -128,8 +131,6 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener private float mMinScale; /** Maximum scale to limit scaling to, 0 means no limit. */ private float mMaxScale; - /** When {@code true}, prevents scale end gesture from falsely triggering a fling. */ - private boolean mFlingDebounce; // To support translation [i.e. panning] /** Runnable that can move the image */ @@ -258,10 +259,7 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (mTransformsEnabled) { - if (!mFlingDebounce) { - mTranslateRunnable.start(velocityX, velocityY); - } - mFlingDebounce = false; + mTranslateRunnable.start(velocityX, velocityY); } return true; } @@ -292,7 +290,6 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener mDoubleTapDebounce = true; resetTransformations(); } - mFlingDebounce = true; } @Override @@ -934,12 +931,9 @@ public class PhotoView extends View implements GestureDetector.OnGestureListener sCropPaint.setColor(resources.getColor(R.color.photo_crop_highlight_color)); sCropPaint.setStyle(Style.STROKE); sCropPaint.setStrokeWidth(resources.getDimension(R.dimen.photo_crop_stroke_width)); - - sHasMultitouchDistinct = context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT); } - mGestureDetector = new GestureDetector(context, this, null, !sHasMultitouchDistinct); + mGestureDetector = new GestureDetectorCompat(context, this, null); mScaleGetureDetector = new ScaleGestureDetector(context, this); mScaleRunnable = new ScaleRunnable(this); mTranslateRunnable = new TranslateRunnable(this); -- cgit v1.2.3