爲了增強鼠標響應事件,Android提供了GestureDetector手勢識別類。經過GestureDetector.OnGestureListener來獲取當前被觸發的操做手勢(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling),具體包括如下幾種:html
boolean onDoubleTap(MotionEvent e)
解釋:雙擊的第二下Touch down時觸發 java
boolean onDoubleTapEvent(MotionEvent e)
解釋:雙擊的第二下Touch down和up都會觸發,可用e.getAction()區分。 android
boolean onDown(MotionEvent e)
解釋:Touch down時觸發 ide
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解釋:Touch了滑動一點距離後,up時觸發。 函數
void onLongPress(MotionEvent e)
解釋:Touch了不移動一直Touch down時觸發 spa
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解釋:Touch了滑動時觸發。 code
void onShowPress(MotionEvent e)
解釋:Touch了尚未滑動時觸發 orm
(與onDown,onLongPress比較
onDown只要Touch down必定馬上觸發。
而Touchdown後過一會沒有滑動先觸發onShowPress再是onLongPress。
因此Touchdown後一直不滑動,onDown->onShowPress->onLongPress這個順序觸發。htm
boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
解釋:上面這兩個函數都是在touch down後又沒有滑動(onScroll),又沒有長按(onLongPress),而後Touchup時觸發。事件
點擊一下很是快的(不滑動)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
點擊一下稍微慢點的(不滑動)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
----------------------------------------------------------------------------------------------------------------------
下面以我對onDoubleTapEvent()的實際運用說明:
遇到的問題是:
Launcher在主界面滑動頁面時,快速滑動,(頁面同時有onFling()和雙擊的監聽),因爲滑動過快同時觸發了雙擊事件的監聽。
解決:
雙擊事件的監聽選擇onDoubleTapEvent()而不是onDoubleTap(),由於前者是第二次按下down和up均可以監聽到,使得兩次的座標是同一點。代碼以下:
public class LauncherGestureListener extends SimpleOnGestureListener { private float mFlingVelocitySlop = 1000; //滑動,向上下左右,位移和速度 @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { float deltaX = e2.getX() - e1.getX(); float deltaY = e2.getY() - e1.getY(); if (Math.abs(deltaY) > Math.abs(deltaX)) { if (Math.abs(deltaY) >= LauncherApplication.mScreenDimens.height / 10) { if (velocityY > mFlingVelocitySlop) { LauncherGestureManager.onGestureCompleted(LauncherGestureType.FLING_DOWN); } if (velocityY < -mFlingVelocitySlop) { LauncherGestureManager.onGestureCompleted(LauncherGestureType.FLING_UP); } } } else { if (velocityX > mFlingVelocitySlop) { LauncherGestureManager.onGestureCompleted(LauncherGestureType.FLING_RIGHT); } if (velocityX < -mFlingVelocitySlop) { LauncherGestureManager.onGestureCompleted(LauncherGestureType.FLING_LEFT); } } return false; } private double down = 0; private double up = 0; //雙擊事件 @Override public boolean onDoubleTapEvent(MotionEvent e) { int action = e.getAction(); double x = e.getX(); if (action == MotionEvent.ACTION_DOWN) { down = x; } else if (action == MotionEvent.ACTION_UP) { up = x; } if (down == up) { //事件知足,再作其餘事情 LauncherGestureManager.onGestureCompleted(LauncherGestureType.DOUBLE_TAP); } return false; } }
-------------------------------------------------------------
給一個View添加相應的事件監聽流程:
public class HomeWindow extends ViewGroup{ private LauncherGestureManager mGestureManager = new LauncherGestureManager(); @Override public boolean dispatchTouchEvent(MotionEvent ev) { mGestureManager.dispatchTouchEvent(ev); return super.dispatchTouchEvent(ev); } }
public class LauncherGestureManager { public LauncherGestureManager() { mGestureDetector = new GestureDetector(LauncherApplication.mContext, new LauncherGestureListener()); } public void dispatchTouchEvent(MotionEvent ev) { mGestureDetector.onTouchEvent(ev); } }