标签:android style blog java color 使用
应用如果需要复杂的手势匹配,这时候可以使用GestureDetector来实现。
实现步骤:
1、实现OnGestureListener类,也可继承SimpleOnGestureListener类然后复写相应函数;
2、创建一个GestureDetector类对象,然后new一个第1步中自定义的监听类对象作为参数穿进去;
3、在接收到MotionEvent事件时,调用OnGestureListener.onTouchEvent(onTouchEvent)函数。
对手势匹配做的一些自定义处理在手势监听类中实现。
下面对以上三步做一些简单分析:先看GestureDetector构造函数
public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
if (handler != null) {
mHandler = new GestureHandler(handler);
} else {
mHandler = new GestureHandler();
}
mListener = listener;
if (listener instanceof OnDoubleTapListener) {
setOnDoubleTapListener((OnDoubleTapListener) listener);
}
init(context);
}从构造函数看出new一个GestureDetector对象需要一个OnGestureListener对象,该对象保存在mListener中,如果手势监听是继承SimpleOnGestureListener类,那么还会调用setOnDoubleTapListener()。init函数做一些初始化函数,先不看。
接着看第3步OnGestureListener.onTouchEvent(onTouchEvent)函数处理。此函数稍微有点长,分段阅读
public boolean onTouchEvent(MotionEvent ev) {
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 0);
}
final int action = ev.getAction();
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final boolean pointerUp =
(action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP;
final int skipIndex = pointerUp ? ev.getActionIndex() : -1;
// Determine focal point
float sumX = 0, sumY = 0;
final int count = ev.getPointerCount();
for (int i = 0; i < count; i++) {
if (skipIndex == i) continue;
sumX += ev.getX(i);
sumY += ev.getY(i);
}
final int div = pointerUp ? count - 1 : count;
final float focusX = sumX / div;
final float focusY = sumY / div;
boolean handled = false;
InputEventConsistencyVerifier是调试用的,mVelocityTracker是一个速度追踪类对象,紧接着的这段代码逻辑是求一个MotionEvent的中心点,这边调试时发现getPointerCount只有一个点而已,不管是点击或滑动。接着往下看 switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
mDownFocusX = mLastFocusX = focusX;
mDownFocusY = mLastFocusY = focusY;
// Cancel long press and taps
cancelTaps();
break;
case MotionEvent.ACTION_POINTER_UP:
mDownFocusX = mLastFocusX = focusX;
mDownFocusY = mLastFocusY = focusY;
// Check the dot product of current velocities.
// If the pointer that left was opposing another velocity vector, clear.
mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
final int upIndex = ev.getActionIndex();
final int id1 = ev.getPointerId(upIndex);
final float x1 = mVelocityTracker.getXVelocity(id1);
final float y1 = mVelocityTracker.getYVelocity(id1);
for (int i = 0; i < count; i++) {
if (i == upIndex) continue;
final int id2 = ev.getPointerId(i);
final float x = x1 * mVelocityTracker.getXVelocity(id2);
final float y = y1 * mVelocityTracker.getYVelocity(id2);
final float dot = x + y;
if (dot < 0) {
mVelocityTracker.clear();
break;
}
}
break;
case MotionEvent.ACTION_DOWN:
if (mDoubleTapListener != null) {
boolean hadTapMessage = mHandler.hasMessages(TAP);
if (hadTapMessage) mHandler.removeMessages(TAP);
if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
// This is a second tap
mIsDoubleTapping = true;
// Give a callback with the first tap of the double-tap
handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
// Give a callback with down event of the double-tap
handled |= mDoubleTapListener.onDoubleTapEvent(ev);
} else {
// This is a first tap
mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
}
}
mDownFocusX = mLastFocusX = focusX;
mDownFocusY = mLastFocusY = focusY;
if (mCurrentDownEvent != null) {
mCurrentDownEvent.recycle();
}
mCurrentDownEvent = MotionEvent.obtain(ev);
mAlwaysInTapRegion = true;
mAlwaysInBiggerTapRegion = true;
mStillDown = true;
mInLongPress = false;
mDeferConfirmSingleTap = false;
if (mIsLongpressEnabled) {
mHandler.removeMessages(LONG_PRESS);
mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
+ TAP_TIMEOUT + LONGPRESS_TIMEOUT);
}
mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
handled |= mListener.onDown(ev);
break;
对于ACTION_DOWN事件,调用mListener.onDown(ev);处理,mListener是指向第1步中定义的手势监听类对象。对于MotionEvent.ACTION_MOVE事件,调用mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);函数,mCurrentDownEvent是当前滑动手势中的按下点,ev是当前触摸点,scrollX、scrollY是当前触摸点跟上一个触摸点的x/y轴偏移量。对于ACTION_UP事件,调用mListener.onSingleTapUp(ev)或者mListener.onFling(mCurrentDownEvent, ev, velocityX, velocityY);函数。
未完待续。
android4.4之GestureDetector(手势识别),布布扣,bubuko.com
android4.4之GestureDetector(手势识别)
标签:android style blog java color 使用
原文地址:http://blog.csdn.net/guoqifa29/article/details/37956611