GestureDetector.java revision 45f2ca7f7d9fac55aa228e022f46ecbac8712a15
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powellimport android.content.Context; 20216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powellimport android.os.Build; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Detects various gestures and events using the supplied {@link MotionEvent}s. 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The {@link OnGestureListener} callback will notify users when a particular 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * motion event has occurred. This class should only be used with {@link MotionEvent}s 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reported via touch (don't use for trackball events). 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To use this class: 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Create an instance of the {@code GestureDetector} for your {@link View} 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be executed when the events occur. 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GestureDetector { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The listener that is used to notify when gestures occur. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If you want to listen for all the different gestures then implement 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this interface. If you only want to listen for a subset it might 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be easier to extend {@link SimpleOnGestureListener}. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnGestureListener { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when a tap occurs with the down {@link MotionEvent} 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that triggered it. This will be triggered immediately for 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * every down event. All other events should be preceded by this. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The down motion event. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onDown(MotionEvent e); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The user has performed a down {@link MotionEvent} and not performed 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a move or up yet. This event is commonly used to provide visual 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * feedback to the user to let them know that their action has been 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * recognized i.e. highlight an element. 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The down motion event 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onShowPress(MotionEvent e); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when a tap occurs with the up {@link MotionEvent} 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that triggered it. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The up motion event that completed the first tap 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the event is consumed, else false 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onSingleTapUp(MotionEvent e); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when a scroll occurs with the initial on down {@link MotionEvent} and the 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * current move {@link MotionEvent}. The distance in x and y is also supplied for 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * convenience. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e1 The first down motion event that started the scrolling. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e2 The move motion event that triggered the current onScroll. 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param distanceX The distance along the X axis that has been scrolled since the last 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call to onScroll. This is NOT the distance between {@code e1} 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@code e2}. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param distanceY The distance along the Y axis that has been scrolled since the last 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call to onScroll. This is NOT the distance between {@code e1} 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@code e2}. 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the event is consumed, else false 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when a long press occurs with the initial on down {@link MotionEvent} 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that trigged it. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The initial on down motion event that started the longpress. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onLongPress(MotionEvent e); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified of a fling event when it occurs with the initial on down {@link MotionEvent} 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and the matching up {@link MotionEvent}. The calculated velocity is supplied along 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the x and y axis in pixels per second. 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e1 The first down motion event that started the fling. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e2 The move motion event that triggered the current onFling. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param velocityX The velocity of this fling measured in pixels per second 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * along the x axis. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param velocityY The velocity of this fling measured in pixels per second 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * along the y axis. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the event is consumed, else false 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The listener that is used to notify when a double-tap or a confirmed 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * single-tap occur. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface OnDoubleTapListener { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when a single-tap occurs. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unlike {@link OnGestureListener#onSingleTapUp(MotionEvent)}, this 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will only be called after the detector is confident that the user's 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * first tap is not followed by a second tap leading to a double-tap 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * gesture. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The down motion event of the single-tap. 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the event is consumed, else false 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onSingleTapConfirmed(MotionEvent e); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when a double-tap occurs. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The down motion event of the first tap of the double-tap. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the event is consumed, else false 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onDoubleTap(MotionEvent e); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notified when an event within a double-tap gesture occurs, including 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the down, move, and up events. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param e The motion event that occurred during the double-tap gesture. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the event is consumed, else false 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean onDoubleTapEvent(MotionEvent e); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A convenience class to extend when you only want to listen for a subset 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of all the gestures. This implements all methods in the 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link OnGestureListener} and {@link OnDoubleTapListener} but does 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * nothing and return {@code false} for all applicable methods. 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onSingleTapUp(MotionEvent e) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onLongPress(MotionEvent e) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onScroll(MotionEvent e1, MotionEvent e2, 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float distanceX, float distanceY) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float velocityY) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onShowPress(MotionEvent e) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onDown(MotionEvent e) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onDoubleTap(MotionEvent e) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onDoubleTapEvent(MotionEvent e) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onSingleTapConfirmed(MotionEvent e) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: ViewConfiguration 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBiggerTouchSlopSquare = 20 * 20; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTouchSlopSquare; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDoubleTapSlopSquare; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mMinimumFlingVelocity; 2024296fc4d326447875c26a925f12b3935632f13bbRomain Guy private int mMaximumFlingVelocity; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout(); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout(); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout(); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // constants for Message.what used by GestureHandler below 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SHOW_PRESS = 1; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LONG_PRESS = 2; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int TAP = 3; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Handler mHandler; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final OnGestureListener mListener; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnDoubleTapListener mDoubleTapListener; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStillDown; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mInLongPress; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAlwaysInTapRegion; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAlwaysInBiggerTapRegion; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MotionEvent mCurrentDownEvent; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MotionEvent mPreviousUpEvent; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * True when the user is still touching for the second tap (down, move, and 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * up events). Can only be true if there is a double tap listener attached. 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsDoubleTapping; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mLastMotionY; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mLastMotionX; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsLongpressEnabled; 235216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell 236216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell /** 237216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * True if we are at a target API level of >= Froyo or the developer can 238216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * explicitly set it. If true, input events with > 1 pointer will be ignored 239216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * so we can work side by side with multitouch gesture detectors. 240216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell */ 241216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell private boolean mIgnoreMultitouch; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Determines speed during touch scrolling 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private VelocityTracker mVelocityTracker; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GestureHandler extends Handler { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GestureHandler() { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GestureHandler(Handler handler) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(handler.getLooper()); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SHOW_PRESS: 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener.onShowPress(mCurrentDownEvent); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LONG_PRESS: 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchLongPress(); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TAP: 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the user's finger is still down, do not count it as a tap 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDoubleTapListener != null && !mStillDown) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Unknown message " + msg); //never 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a GestureDetector with the supplied listener. 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This variant of the constructor should be used from a non-UI thread 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (as it allows specifying the Handler). 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener the listener invoked for all the callbacks, this must 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not be null. 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler the handler to use 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if either {@code listener} or 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@code handler} is null. 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated Use {@link #GestureDetector(android.content.Context, 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.view.GestureDetector.OnGestureListener, android.os.Handler)} instead. 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GestureDetector(OnGestureListener listener, Handler handler) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, listener, handler); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a GestureDetector with the supplied listener. 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may only use this constructor from a UI thread (this is the usual situation). 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.os.Handler#Handler() 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener the listener invoked for all the callbacks, this must 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not be null. 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if {@code listener} is null. 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated Use {@link #GestureDetector(android.content.Context, 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android.view.GestureDetector.OnGestureListener)} instead. 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GestureDetector(OnGestureListener listener) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(null, listener, null); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a GestureDetector with the supplied listener. 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may only use this constructor from a UI thread (this is the usual situation). 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.os.Handler#Handler() 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application's context 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener the listener invoked for all the callbacks, this must 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not be null. 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if {@code listener} is null. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GestureDetector(Context context, OnGestureListener listener) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, listener, null); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a GestureDetector with the supplied listener. 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may only use this constructor from a UI thread (this is the usual situation). 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.os.Handler#Handler() 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application's context 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener the listener invoked for all the callbacks, this must 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not be null. 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler the handler to use 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if {@code listener} is null. 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GestureDetector(Context context, OnGestureListener listener, Handler handler) { 347216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell this(context, listener, handler, context != null && 348216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.FROYO); 349216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell } 350216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell 351216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell /** 352216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * Creates a GestureDetector with the supplied listener. 353216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * You may only use this constructor from a UI thread (this is the usual situation). 354216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * @see android.os.Handler#Handler() 355216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * 356216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * @param context the application's context 357216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * @param listener the listener invoked for all the callbacks, this must 358216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * not be null. 359216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * @param handler the handler to use 360216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * @param ignoreMultitouch whether events involving more than one pointer should 361216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * be ignored. 362216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * 363216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell * @throws NullPointerException if {@code listener} is null. 364216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell */ 365216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell public GestureDetector(Context context, OnGestureListener listener, Handler handler, 366216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell boolean ignoreMultitouch) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (handler != null) { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new GestureHandler(handler); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new GestureHandler(); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener instanceof OnDoubleTapListener) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setOnDoubleTapListener((OnDoubleTapListener) listener); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 376216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell init(context, ignoreMultitouch); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell private void init(Context context, boolean ignoreMultitouch) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener == null) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("OnGestureListener must not be null"); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsLongpressEnabled = true; 384216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mIgnoreMultitouch = ignoreMultitouch; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fallback to support pre-donuts releases 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int touchSlop, doubleTapSlop; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (context == null) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //noinspection deprecation 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project touchSlop = ViewConfiguration.getTouchSlop(); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doubleTapSlop = ViewConfiguration.getDoubleTapSlop(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //noinspection deprecation 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinimumFlingVelocity = ViewConfiguration.getMinimumFlingVelocity(); 3944296fc4d326447875c26a925f12b3935632f13bbRomain Guy mMaximumFlingVelocity = ViewConfiguration.getMaximumFlingVelocity(); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewConfiguration configuration = ViewConfiguration.get(context); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project touchSlop = configuration.getScaledTouchSlop(); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doubleTapSlop = configuration.getScaledDoubleTapSlop(); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity(); 4004296fc4d326447875c26a925f12b3935632f13bbRomain Guy mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity(); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTouchSlopSquare = touchSlop * touchSlop; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDoubleTapSlopSquare = doubleTapSlop * doubleTapSlop; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the listener which will be called for double-tap and related 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * gestures. 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param onDoubleTapListener the listener invoked for all the callbacks, or 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * null to stop listening for double-tap gestures. 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDoubleTapListener = onDoubleTapListener; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set whether longpress is enabled, if this is enabled when a user 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * presses and holds down you get a longpress event and nothing further. 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If it's disabled the user can press and hold down and then later 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * moved their finger and you will get scroll events. By default 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * longpress is enabled. 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isLongpressEnabled whether longpress should be enabled. 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setIsLongpressEnabled(boolean isLongpressEnabled) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsLongpressEnabled = isLongpressEnabled; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if longpress is enabled, else false. 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isLongpressEnabled() { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIsLongpressEnabled; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Analyzes the given motion event and if applicable triggers the 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appropriate callbacks on the {@link OnGestureListener} supplied. 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param ev The current motion event. 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the {@link OnGestureListener} consumed the event, 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * else false. 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int action = ev.getAction(); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float y = ev.getY(); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float x = ev.getX(); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVelocityTracker == null) { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker = VelocityTracker.obtain(); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker.addMovement(ev); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = false; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 457216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell switch (action & MotionEvent.ACTION_MASK) { 458216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell case MotionEvent.ACTION_POINTER_DOWN: 459216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell if (mIgnoreMultitouch) { 460216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell // Multitouch event - abort. 461216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell cancel(); 462216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell } 463216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell break; 464216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell 465216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell case MotionEvent.ACTION_POINTER_UP: 466216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell // Ending a multitouch gesture and going back to 1 finger 467216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell if (mIgnoreMultitouch && ev.getPointerCount() == 2) { 468b125dc5599468a09d82751cd76152071ae485afbDianne Hackborn int index = (((action & MotionEvent.ACTION_POINTER_INDEX_MASK) 469b125dc5599468a09d82751cd76152071ae485afbDianne Hackborn >> MotionEvent.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0; 470b125dc5599468a09d82751cd76152071ae485afbDianne Hackborn mLastMotionX = ev.getX(index); 471b125dc5599468a09d82751cd76152071ae485afbDianne Hackborn mLastMotionY = ev.getY(index); 472216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mVelocityTracker.recycle(); 473216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mVelocityTracker = VelocityTracker.obtain(); 474216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell } 475216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell break; 476216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_DOWN: 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDoubleTapListener != null) { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hadTapMessage = mHandler.hasMessages(TAP); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hadTapMessage) mHandler.removeMessages(TAP); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage && 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a second tap 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsDoubleTapping = true; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Give a callback with the first tap of the double-tap 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Give a callback with down event of the double-tap 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled |= mDoubleTapListener.onDoubleTapEvent(ev); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a first tap 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastMotionX = x; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastMotionY = y; 49745f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell if (mCurrentDownEvent != null) { 49845f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell mCurrentDownEvent.recycle(); 49945f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentDownEvent = MotionEvent.obtain(ev); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlwaysInTapRegion = true; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlwaysInBiggerTapRegion = true; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStillDown = true; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInLongPress = false; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsLongpressEnabled) { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(LONG_PRESS); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + TAP_TIMEOUT + LONGPRESS_TIMEOUT); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled |= mListener.onDown(ev); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_MOVE: 516216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell if (mInLongPress || (mIgnoreMultitouch && ev.getPointerCount() > 1)) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float scrollX = mLastMotionX - x; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float scrollY = mLastMotionY - y; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDoubleTapping) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Give the move events of the double-tap 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled |= mDoubleTapListener.onDoubleTapEvent(ev); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mAlwaysInTapRegion) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int deltaX = (int) (x - mCurrentDownEvent.getX()); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int deltaY = (int) (y - mCurrentDownEvent.getY()); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int distance = (deltaX * deltaX) + (deltaY * deltaY); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (distance > mTouchSlopSquare) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastMotionX = x; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastMotionY = y; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlwaysInTapRegion = false; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(TAP); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(SHOW_PRESS); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(LONG_PRESS); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (distance > mBiggerTouchSlopSquare) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlwaysInBiggerTapRegion = false; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastMotionX = x; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastMotionY = y; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_UP: 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStillDown = false; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MotionEvent currentUpEvent = MotionEvent.obtain(ev); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsDoubleTapping) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Finally, give the up event of the double-tap 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled |= mDoubleTapListener.onDoubleTapEvent(ev); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mInLongPress) { 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(TAP); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInLongPress = false; 556f5b4b98fada53d91c4c2ebeb5a1d33ccc95c94d2The Android Open Source Project } else if (mAlwaysInTapRegion) { 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = mListener.onSingleTapUp(ev); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // A fling must travel the minimum tap distance 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final VelocityTracker velocityTracker = mVelocityTracker; 5624296fc4d326447875c26a925f12b3935632f13bbRomain Guy velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float velocityY = velocityTracker.getYVelocity(); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float velocityX = velocityTracker.getXVelocity(); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((Math.abs(velocityY) > mMinimumFlingVelocity) 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (Math.abs(velocityX) > mMinimumFlingVelocity)){ 56845f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell handled = mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57145f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell if (mPreviousUpEvent != null) { 57245f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell mPreviousUpEvent.recycle(); 57345f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell } 57445f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell // Hold the event we obtained above - listeners may have changed the original. 57545f2ca7f7d9fac55aa228e022f46ecbac8712a15Adam Powell mPreviousUpEvent = currentUpEvent; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker.recycle(); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVelocityTracker = null; 578b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mIsDoubleTapping = false; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(SHOW_PRESS); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(LONG_PRESS); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_CANCEL: 583216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell cancel(); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return handled; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 588216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell private void cancel() { 589216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mHandler.removeMessages(SHOW_PRESS); 590216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mHandler.removeMessages(LONG_PRESS); 591216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mHandler.removeMessages(TAP); 592216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mVelocityTracker.recycle(); 593216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mVelocityTracker = null; 594216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mIsDoubleTapping = false; 595216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mStillDown = false; 596216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell if (mInLongPress) { 597216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell mInLongPress = false; 598216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell } 599216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell } 600216bccf804db9c972b317620a27de6a8adf7fbfeAdam Powell 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp, 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MotionEvent secondDown) { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mAlwaysInBiggerTapRegion) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deltaX = (int) firstDown.getX() - (int) secondDown.getX(); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int deltaY = (int) firstDown.getY() - (int) secondDown.getY(); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void dispatchLongPress() { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.removeMessages(TAP); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInLongPress = true; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener.onLongPress(mCurrentDownEvent); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 622