手勢監聽GestureDetector,OnGestureListener

爲了增強鼠標響應事件,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);
    }
}
相關文章
相關標籤/搜索