为了加强鼠标响应事件,Android提供了GestureDetector手势识别类。通过GestureDetector.OnGestureListener来获取当前被触发的操作手势(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling),具体包括以下几种:
boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
boolean onDown(MotionEvent e)
解释:Touch down时触发
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
解释:Touch了滑动一点距离后,up时触发。
void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
解释:Touch了滑动时触发。
void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较
onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
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); } }