ジェスチャーリスニングGestureDetector,OnGestureListener

3951 ワード

マウス応答イベントを強化するために、AndroidはGestureDetectorジェスチャー識別クラスを提供しています.GestureDetectorを通ります.OnGestureListenerは、現在トリガーされている操作ジェスチャー(Single Tap Up、Show Press、Long Press、Scroll、Down、Fling)を取得します.具体的には、以下のものが含まれます.
boolean onDoubleTap(MotionEvent e)解釈:ダブルクリックした2番目の下Touch down時にトリガーする
boolean onDoubleTapEvent(MotionEvent e)解釈:ダブルクリックした2番目の下のTouch downとupがトリガーされ、e.getAction()で区別できます. 
boolean onDown(MotionEvent)解釈:Touch down時トリガ
boolean onFling(MotionEvent e 1,MotionEvent e 2,float velocityX,float velocityY)は、Touchが少し距離を滑った後、up時にトリガーされると説明している. 
void onLongPress(MotionEvent)解釈:Touchが移動しないでずっとTouch downの時トリガします
boolean onScroll(MotionEvent e 1,MotionEvent e 2,float distanceX,float distanceY)解釈:Touchがスライドしたときにトリガーされる. 
void onShowPress(MotionEvent)解釈:Touchがまだスライドしていないときにトリガー
(onDown,onLongPressと比較onDownはTouch downが必ずすぐにトリガーされる.Touchdownの後しばらくスライドせずにonShowPress、さらにonLongPressをトリガーする.だからTouchdownの後はずっとスライドせず、onDown->onShowPress->onLongPressという順番でトリガーされる.
boolean onSingleTapConfirmed(MotionEvent e)boolean onSingleTapUp(MotionEvent e)は、上記の2つの関数はtouch down後もスライド(onScroll)がなく、長押し(onLongPress)がなく、Touchup時にトリガーされると説明しています.
非常に速い(スライドしない)Touchupをクリック:onDown->onSingleTapUp->onSingleTapConfirmed少し遅い(スライドしない)Touchup:onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
----------------------------------------------------------------------------------------------------------------------
以下、onDoubleTapEvent()の実際の運用について説明します.
問題は次のとおりです.
Launcherはメインインタフェースでページをスライドすると、すばやくスライドし、(ページにはonFling()とダブルクリックのリスニングが同時にあります)、スライドが速すぎるためダブルクリックイベントのリスニングが同時にトリガーされます.
解決:
イベントの傍受選択をダブルクリックすると、onDoubleTapEvent()ではなくonDoubleTap()が選択されます.前者はdownとupを2回押しても傍受できるので、2回の座標が同じになります.コードは次のとおりです.
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);
    }
}