public boolean onTouchEvent(MotionEvent ev) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev);//把所有事件都添加到速度追踪器,为计算速度做准备 boolean handled = false; final int action = ev.getAction(); //获取Action // int idx = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;//获取触摸事件的序号 int idx = ev.getPointerId(ev.getActionIndex());//获取触摸事件的id switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: { EventInfo info = new EventInfo(MotionEvent.obtain(ev)); this.addEventIntoList(info);//将手势信息保存到队列中 if (mDoubleTapListener != null) {//如果双击监听器不为null if (mHandler.hasMessages(TAP_DOUBLE)) { MultiMotionEvent e = new MultiMotionEvent(ev); EventInfo origInfo = checkForDoubleTap(e);//检查是否构成双击事件 if (origInfo != null) { info.mIsDoubleTapping = true; handled |= mDoubleTapListener.onDoubleTap(origInfo.mCurrentDownEvent); handled |= mDoubleTapListener.onDoubleTapEvent(e); } } if (!info.mIsDoubleTapping) {//当前事件不构成双击事件,那么发送延迟消息以判断onSingleTapConfirmed事件 mHandler.sendMessageDelayed(mHandler.obtainMessage(TAP_SINGLE, idx), DOUBLE_TAP_TIMEOUT); // Log.d(MYTAG, CLASS_NAME + ": add TAP_SINGLE"); } } // 记录X坐标和Y坐标 info.mLastMotionX = info.mCurrentDownEvent.getX(); info.mLastMotionY = info.mCurrentDownEvent.getY(); if (mIsLongpressEnabled) {//允许长按 mHandler.removeMessages(LONG_PRESS, idx); mHandler.sendMessageAtTime(mHandler.obtainMessage(LONG_PRESS, idx), info.mCurrentDownEvent.getEventTime() + TAP_TIMEOUT + LONGPRESS_TIMEOUT);//延时消息以触发长按手势 // Log.d(MYTAG, CLASS_NAME + // ":add LONG_PRESS to handler for idx " + idx); } mHandler.sendMessageAtTime(mHandler.obtainMessage(SHOW_PRESS, idx), info.mCurrentDownEvent.getEventTime() + TAP_TIMEOUT);// 延时消息,触发showPress手势 handled |= mListener.onDown(info.mCurrentDownEvent);//触发onDown() break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: { MultiMotionEvent currentUpEvent = new MultiMotionEvent(ev); if (idx >= sEventInfos.size()) { // Log.e(MYTAG, CLASS_NAME + ":ACTION_POINTER_UP, idx=" + idx + ", while sEventInfos.size()=" + sEventInfos.size()); break; } EventInfo info = sEventInfos.get(currentUpEvent.getId()); if (info == null) { // Log.e(MYTAG, CLASS_NAME + ":ACTION_POINTER_UP, idx=" + idx + ", Info = null"); break; } info.mStillDown = false; if (info.mIsDoubleTapping) { //处于双击状态,则触发onDoubleTapEvent事件 handled |= mDoubleTapListener.onDoubleTapEvent(currentUpEvent); } else if (info.mInLongPress) {//处于长按状态 mHandler.removeMessages(TAP_SINGLE, idx);//可以无视这行代码 info.mInLongPress = false; } else if (info.mAlwaysInTapRegion) {//尚未移动过 if (mHandler.hasMessages(TAP_SINGLE, idx)) {//还在双击的时间阀值内,所以要为双击判断做额外处理 mHandler.removeMessages(TAP_SINGLE, idx); info.mPreviousUpEvent = new MultiMotionEvent(MotionEvent.obtain(ev)); int index = this.addIntoTheMinIndex(info);// 把当前事件放入队列,等待双击的判断 mHandler.sendMessageAtTime(mHandler.obtainMessage(TAP_DOUBLE, index), info.mCurrentDownEvent.getEventTime() + DOUBLE_TAP_TIMEOUT); // 将双击超时判断添加到Handler // Log.d(MYTAG, CLASS_NAME + ": add TAP_DOUBLE"); } handled = mListener.onSingleTapUp(currentUpEvent);//触发onSingleTapUp事件 } else { // A fling must travel the minimum tap distance final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);//计算1秒钟内的滑动速度 //获取X和Y方向的速度 final float velocityX = velocityTracker.getXVelocity(idx); final float velocityY = velocityTracker.getYVelocity(idx); // Log.i(MYTAG, CLASS_NAME + ":ACTION_POINTER_UP, idx=" + idx + // ", vx=" + velocityX + ", vy=" + velocityY); // 触发滑动事件 if ((Math.abs(velocityY) > mMinimumFlingVelocity) || (Math.abs(velocityX) > mMinimumFlingVelocity)) { handled = mListener.onFling(info.mCurrentDownEvent, currentUpEvent, velocityX, velocityY); } } // Hold the event we obtained above - listeners may have changed the // original. if (action == MotionEvent.ACTION_UP) { //释放速度追踪器 mVelocityTracker.recycle(); mVelocityTracker = null; // Log.w(MYTAG, CLASS_NAME + // ":ACTION_POINTER_UP, mVelocityTracker.recycle()"); } info.mIsDoubleTapping = false; // Log.d(MYTAG, CLASS_NAME + "remove LONG_PRESS"); // 移除showPress和长按消息 mHandler.removeMessages(SHOW_PRESS, idx); mHandler.removeMessages(LONG_PRESS, idx); removeEventFromList(currentUpEvent.getId());//手指离开,则从队列中删除手势信息 break; } case MotionEvent.ACTION_MOVE: for (int rIdx = 0; rIdx < ev.getPointerCount(); rIdx++) {//因为无法确定当前发生移动的是哪个手指,所以遍历处理所有手指 MultiMotionEvent e = new MultiMotionEvent(ev, rIdx); if (e.getId() >= sEventInfos.size()) { // Log.e(MYTAG, CLASS_NAME + ":ACTION_MOVE, idx=" + rIdx + ", while sEventInfos.size()=" + sEventInfos.size()); break; } EventInfo info = sEventInfos.get(e.getId()); if (info == null) { // Log.e(MYTAG, CLASS_NAME + ":ACTION_MOVE, idx=" + rIdx + ", Info = null"); break; } if (info.mInLongPress) { //长按,则不处理move事件 break; } //当前坐标 float x = e.getX(); float y = e.getY(); //距离上次事件移动的位置 final float scrollX = x - info.mLastMotionX; final float scrollY = y - info.mLastMotionY; if (info.mIsDoubleTapping) {//双击事件 handled |= mDoubleTapListener.onDoubleTapEvent(e); } else if (info.mAlwaysInTapRegion) {//该手势尚未移动过(移动的距离小于mTouchSlopSquare,视为未移动过) // 计算从落下到当前事件,移动的距离 final int deltaX = (int) (x - info.mCurrentDownEvent.getX()); final int deltaY = (int) (y - info.mCurrentDownEvent.getY()); // Log.d(MYTAG, CLASS_NAME + "deltaX="+deltaX+";deltaY=" + // deltaX +"mTouchSlopSquare=" + mTouchSlopSquare); int distance = (deltaX * deltaX) + (deltaY * deltaY); if (distance > mTouchSlopSquare) { // 移动距离超过mTouchSlopSquare handled = mListener.onScroll(info.mCurrentDownEvent, e, scrollX, scrollY); info.mLastMotionX = e.getX(); info.mLastMotionY = e.getY(); info.mAlwaysInTapRegion = false; // Log.d(MYTAG, CLASS_NAME + // ":remove LONG_PRESS for idx" + rIdx + // ",mTouchSlopSquare("+mTouchSlopSquare+"), distance("+distance+")"); // 清除onSingleTapConform,showPress,longPress三种消息 int id = e.getId(); mHandler.removeMessages(TAP_SINGLE, id); mHandler.removeMessages(SHOW_PRESS, id); mHandler.removeMessages(LONG_PRESS, id); } if (distance > mBiggerTouchSlopSquare) {//移动距离大于mBiggerTouchSlopSquare,则无法构成双击事件 info.mAlwaysInBiggerTapRegion = false; } } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {//之前已经移动过了 handled = mListener.onScroll(info.mCurrentDownEvent, e, scrollX, scrollY); info.mLastMotionX = x; info.mLastMotionY = y; } } break; case MotionEvent.ACTION_CANCEL: cancel();//清理 } return handled; } // 清理所有队列 private void cancel() { mHandler.removeMessages(SHOW_PRESS); mHandler.removeMessages(LONG_PRESS); mHandler.removeMessages(TAP_SINGLE); mVelocityTracker.recycle(); mVelocityTracker = null; sEventInfos.clear(); sEventForDoubleTap.clear(); } }
上一页 [1] [2] [3]