下面列出了android.view.MotionEvent#ACTION_POINTER_DOWN 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int action = ev.getActionMasked();
// 手指按下的时候,如果有开启的菜单,只要手指不是落在该Item上,则关闭菜单, 并且不分发事件。
if (action == MotionEvent.ACTION_DOWN) {
int x = (int) ev.getX();
int y = (int) ev.getY();
View openItem = findOpenItem();
if (openItem != null && openItem != getTouchItem(x, y)) {
SwipeItemLayout swipeItemLayout = findSwipeItemLayout(openItem);
if (swipeItemLayout != null) {
swipeItemLayout.close();
return false;
}
}
} else if (action == MotionEvent.ACTION_POINTER_DOWN) {
// FIXME: 2017/3/22 不知道怎么解决多点触控导致可以同时打开多个菜单的bug,先暂时禁止多点触控
return false;
}
return super.dispatchTouchEvent(ev);
}
public boolean onTouchEvent(MotionEvent ev) {
if ((ev.getAction() & MotionEvent.ACTION_POINTER_DOWN) == MotionEvent.ACTION_POINTER_DOWN) {
lastZoomDistance = getZoomDistance(ev);
return true;
}
if ((ev.getAction() & MotionEvent.ACTION_POINTER_UP) == MotionEvent.ACTION_POINTER_UP) {
lastZoomDistance = 0;
zoomModel.commit();
resetLastPointAfterZoom = true;
return true;
}
if (ev.getAction() == MotionEvent.ACTION_MOVE && lastZoomDistance != 0) {
float zoomDistance = getZoomDistance(ev);
zoomModel.setZoom(zoomModel.getZoom() * zoomDistance / lastZoomDistance);
lastZoomDistance = zoomDistance;
return true;
}
return false;
}
private void dumpEvent(MotionEvent event) {
String[] names = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION.").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(", ").append((int) event.getY(i));
if (i + 1 < event.getPointerCount()) {
sb.append(":");
}
}
sb.append("]");
Log.d(TAG, sb.toString());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int x = (int) event.getX();
int offsetX = x - mDownX;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE:
if (isGreaterThanMinSize(mDownX, x) && isCanSrcoll) {
mIPositionCallBack.onPositionChange(getPositionChangeX(offsetX), 0);
return true;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_UP:
if (isGreaterThanMinSize(mDownX, x) && isCanSrcoll) {
mDownX = getPositionChangeX(offsetX);
fixPostion(offsetX);
mEndAnimator.start();
}
break;
}
return super.onTouchEvent(event);
}
private static String actionToString(int action) {
switch (action) {
case MotionEvent.ACTION_DOWN:
return "ACTION_DOWN";
case MotionEvent.ACTION_POINTER_DOWN:
return "ACTION_POINTER_DOWN";
case MotionEvent.ACTION_POINTER_2_DOWN:
return "ACTION_POINTER_2_DOWN";
case MotionEvent.ACTION_POINTER_2_UP:
return "ACTION_POINTER_2_UP";
case MotionEvent.ACTION_POINTER_3_DOWN:
return "ACTION_POINTER_3_DOWN";
case MotionEvent.ACTION_POINTER_3_UP:
return "ACTION_POINTER_3_UP";
case MotionEvent.ACTION_UP:
return "ACTION_UP";
case MotionEvent.ACTION_POINTER_UP:
return "ACTION_POINTER_UP";
case MotionEvent.ACTION_MOVE:
return "ACTION_MOVE";
}
return "?";
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if (mOnActivePseudoListner != null) {
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {
mOnActivePseudoListner.updateActivePseudo(true);
} else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
mOnActivePseudoListner.updateActivePseudo(false);
}
}
return mIsConsumeOnTouch;
}
public void onTouch(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN || event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
LayoutParams layoutParams = (LayoutParams) textureView.getLayoutParams();
if (layoutParams != null && event.getX() >= layoutParams.leftMargin && event.getY() >= layoutParams.topMargin && event.getX() <= layoutParams.leftMargin + layoutParams.width && event.getY() <= layoutParams.topMargin + layoutParams.height) {
setShowOriginal(true);
}
} else if (event.getActionMasked() == MotionEvent.ACTION_UP || event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) {
setShowOriginal(false);
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction() & MotionEvent.ACTION_MASK;
if (mTouchChild == null) {
return false;
}
mVelocityTracker.addMovement(ev);
switch (action) {
case MotionEvent.ACTION_DOWN: {
log(TAG, "onTouchEvent ACTION_DOWN");
if (!mOnTouchableChild) {
return false;
}
break;
}
case MotionEvent.ACTION_MOVE: {
//子view未消费down事件时,mIsBeingDragged为false
log(TAG, "onTouchEvent ACTION_MOVE,mActivePointerId=" + mActivePointerId);
if (mActivePointerId == INVALID_POINTER) {
log(TAG, "onTouchEvent ACTION_MOVE,INVALID_POINTER");
break;
}
int pointerIndex = ev.findPointerIndex(mActivePointerId);
float x = ev.getX(pointerIndex);
float y = ev.getY(pointerIndex);
if (!mIsBeingDragged) {
cancelSpringIfNeeded();
float dx = x - mInitDownX;
float dy = y - mInitDownY;
if ((Math.abs(dx) <= mDragSlop && (Math.abs(dy) <= mDragSlop)) || !canDrag(dx, dy)) {
mLastX = x;
mLastY = y;
return false;
}
mIsBeingDragged = true;
}
performDrag(x - mLastX, y - mLastY);
mLastX = x;
mLastY = y;
break;
}
case MotionEvent.ACTION_POINTER_DOWN:
log(TAG, "onTouchEvent ACTION_POINTER_DOWN");
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
log(TAG, "onTouchEvent ACTION_UP,mActivePointerId=" + mActivePointerId);
if (mActivePointerId == INVALID_POINTER) {
break;
}
onTouchRelease();
break;
}
case MotionEvent.ACTION_POINTER_UP: {
log(TAG, "onTouchEvent ACTION_POINTER_UP,mActivePointerId=" + mActivePointerId);
int activePointerIndex = ev.findPointerIndex(mActivePointerId);
if (activePointerIndex == ev.getActionIndex()) {
onTouchRelease();
}
break;
}
}
return true;
}
public boolean onTouchEvent(@NonNull MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
sX = event.getX();
sY = event.getY();
mPointerIndex1 = event.findPointerIndex(event.getPointerId(0));
mAngle = 0;
mIsFirstTouch = true;
break;
case MotionEvent.ACTION_POINTER_DOWN:
fX = event.getX();
fY = event.getY();
mPointerIndex2 = event.findPointerIndex(event.getPointerId(event.getActionIndex()));
mAngle = 0;
mIsFirstTouch = true;
break;
case MotionEvent.ACTION_MOVE:
if (mPointerIndex1 != INVALID_POINTER_INDEX && mPointerIndex2 != INVALID_POINTER_INDEX && event.getPointerCount() > mPointerIndex2) {
float nfX, nfY, nsX, nsY;
nsX = event.getX(mPointerIndex1);
nsY = event.getY(mPointerIndex1);
nfX = event.getX(mPointerIndex2);
nfY = event.getY(mPointerIndex2);
if (mIsFirstTouch) {
mAngle = 0;
mIsFirstTouch = false;
} else {
calculateAngleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY);
}
if (mListener != null) {
mListener.onRotation(this);
}
fX = nfX;
fY = nfY;
sX = nsX;
sY = nsY;
}
break;
case MotionEvent.ACTION_UP:
mPointerIndex1 = INVALID_POINTER_INDEX;
break;
case MotionEvent.ACTION_POINTER_UP:
mPointerIndex2 = INVALID_POINTER_INDEX;
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.d(TAG, "onTouchEvent --> action = " + (0xFF & ev.getAction()));
if (isHeaderTop && isEnableZoom) {
switch (0xFF & ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_OUTSIDE:
if (!mScalingRunnable.isFinished()) {
mScalingRunnable.abortAnimation();
}
mLastMotionY = ev.getY();
mActivePointerId = ev.getPointerId(0);
mMaxScale = (mScreenHeight / mZoomHeight);
mLastScale = (mZoomContainer.getBottom() / mZoomHeight);
if (onScrollViewZoomListener != null) {
onScrollViewZoomListener.onStart();
}
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "mActivePointerId = " + mActivePointerId);
int j = ev.findPointerIndex(this.mActivePointerId);
if (j == -1) {
Log.e(TAG, "Invalid pointerId = " + mActivePointerId + " in onTouchEvent");
} else {
if (mLastMotionY == -1.0F) {
mLastMotionY = ev.getY(j);
}
if (mZoomContainer.getBottom() >= mZoomHeight) {
LayoutParams localLayoutParams = (LayoutParams) mZoomContainer.getLayoutParams();
ViewGroup.LayoutParams headLayoutParams = mHeaderContainer.getLayoutParams();
float f = ((ev.getY(j) - mLastMotionY + mZoomContainer.getBottom()) / mZoomHeight - mLastScale) / 2.0F + mLastScale;
if ((mLastScale <= 1.0D) && (f < mLastScale)) {
localLayoutParams.height = mZoomHeight;
localLayoutParams.width = mZoomWidth;
localLayoutParams.gravity = Gravity.CENTER;
headLayoutParams.height = mZoomHeight;
mZoomContainer.setLayoutParams(localLayoutParams);
mHeaderContainer.setLayoutParams(headLayoutParams);
return super.onTouchEvent(ev);
}
mLastScale = Math.min(Math.max(f, 1.0F), mMaxScale);
localLayoutParams.height = ((int) (mZoomHeight * mLastScale));
localLayoutParams.width = ((int) (mZoomWidth * mLastScale));
localLayoutParams.gravity = Gravity.CENTER;
headLayoutParams.height = ((int) (mZoomHeight * mLastScale));
if (localLayoutParams.height < mScreenHeight) {
mZoomContainer.setLayoutParams(localLayoutParams);
mHeaderContainer.setLayoutParams(headLayoutParams);
}
mLastMotionY = ev.getY(j);
return true;
}
this.mLastMotionY = ev.getY(j);
}
break;
case MotionEvent.ACTION_UP:
reset();
endScaling();
if (onScrollViewZoomListener != null) {
onScrollViewZoomListener.onFinish();
}
break;
case MotionEvent.ACTION_CANCEL:
int i = ev.getActionIndex();
mLastMotionY = ev.getY(i);
mActivePointerId = ev.getPointerId(i);
break;
case MotionEvent.ACTION_POINTER_DOWN:
onSecondaryPointerUp(ev);
mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
break;
}
}
return super.onTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!isEnabled() || canChildScrollUp() || mIsRefreshing) {
return false;
}
int action = MotionEventCompat.getActionMasked(ev);
int pointerIndex;
switch (action) {
case MotionEvent.ACTION_DOWN:
if(isLogMeasure)
Log.e(TAG, "-->onTouchEvent: ACTION_DOWN");
mIsBeingDragged = false;
notifyStatus(STATUS_INIT);
mActivePointerId = ev.getPointerId(0);
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
return false;
}
mInitDownY = ev.getY(pointerIndex);
break;
case MotionEvent.ACTION_MOVE:
if(isLogMeasure)
Log.e(TAG, "-->onTouchEvent: ACTION_MOVE");
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
return false;
}
float evY = ev.getY(pointerIndex);
checkDragging(evY);
if (mIsBeingDragged) {
float dy = (evY - mInitMotionY) * mDragRate;
if (dy > 0) {
actionMoving(dy);
}
notifyStatus(STATUS_DRAGGING);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if(isLogMeasure)
Log.e(TAG, "-->onTouchEvent: ACTION_POINTER_DOWN");
pointerIndex = MotionEventCompat.getActionIndex(ev);
if (pointerIndex < 0) {
return false;
}
mActivePointerId = ev.getPointerId(pointerIndex);
break;
case MotionEventCompat.ACTION_POINTER_UP:
if(isLogMeasure)
Log.e(TAG, "-->onTouchEvent: ACTION_POINTER_UP");
checkOtherPointerUp(ev);
break;
case MotionEvent.ACTION_UP:
if(isLogMeasure)
Log.e(TAG, "-->onTouchEvent: ACTION_UP");
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
return false;
}
float upY = ev.getY(pointerIndex);
if (mIsBeingDragged) {
float upDy = (upY - mInitMotionY) * mDragRate;
actionUp(upDy);
mIsBeingDragged = false;
}
mActivePointerId = -1;
break;
case MotionEvent.ACTION_CANCEL:
if(isLogMeasure)
Log.e(TAG, "-->onTouchEvent: ACTION_CANCEL");
return false;
}
return true;
}
@Override
public boolean onTouchEventInternal(MotionEvent e) {
if (mPropagateEventsToHostView) {
mHost.propagateEvent(e);
return true;
}
// If more than one pointer are down, we should forward these events to the
// ContentView.
final int action = e.getActionMasked();
if (action == MotionEvent.ACTION_POINTER_DOWN
&& e.getPointerCount() == 2
&& !mScrollStarted) {
mPropagateEventsToHostView = true;
// Some type of multi-touch that should go to the view.
mScrollDirection = ScrollDirection.UNKNOWN;
MotionEvent cancelEvent = MotionEvent.obtain(
e.getDownTime(),
SystemClock.uptimeMillis(),
MotionEvent.ACTION_CANCEL,
0, 0, 0);
mGestureDetector.onTouchEvent(cancelEvent);
propagateAccumulatedEventsAndClear();
mHost.propagateEvent(e);
return true;
}
if (action == MotionEvent.ACTION_UP) {
if (mInLongPress || mInDoubleTap) {
mHost.propagateEvent(e);
mInLongPress = false;
mInDoubleTap = false;
}
}
if (mScrollDirection != ScrollDirection.UNKNOWN) {
if (mAccumulatingEvents) {
mAccumulatedEvents.add(MotionEvent.obtain(e));
}
mGestureDetector.onTouchEvent(e);
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
scrollFinished();
propagateAccumulatedEventsAndClear();
mScrollDirection = ScrollDirection.UNKNOWN;
}
}
return true;
}
public void TrackEvent(MotionEvent event)
{
int pointerIndex = event.getActionIndex();
switch (event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (getBounds().contains((int) event.getX(pointerIndex), (int) event.getY(pointerIndex)))
{
mPressedState = true;
mOuterBitmap.setAlpha(0);
mBoundsBoxBitmap.setAlpha(255);
getVirtBounds().offset((int) event.getX(pointerIndex) - getVirtBounds().centerX(),
(int) event.getY(pointerIndex) - getVirtBounds().centerY());
mBoundsBoxBitmap.setBounds(getVirtBounds());
trackId = event.getPointerId(pointerIndex);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (trackId == event.getPointerId(pointerIndex))
{
mPressedState = false;
axises[0] = axises[1] = 0.0f;
mOuterBitmap.setAlpha(255);
mBoundsBoxBitmap.setAlpha(0);
setVirtBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
mOrigBounds.bottom));
setBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
mOrigBounds.bottom));
SetInnerBounds();
trackId = -1;
}
break;
}
if (trackId == -1)
return;
for (int i = 0; i < event.getPointerCount(); i++)
{
if (trackId == event.getPointerId(i))
{
float touchX = event.getX(i);
float touchY = event.getY(i);
float maxY = getVirtBounds().bottom;
float maxX = getVirtBounds().right;
touchX -= getVirtBounds().centerX();
maxX -= getVirtBounds().centerX();
touchY -= getVirtBounds().centerY();
maxY -= getVirtBounds().centerY();
final float AxisX = touchX / maxX;
final float AxisY = touchY / maxY;
axises[0] = AxisX;
axises[1] = AxisY;
SetInnerBounds();
}
}
}
public boolean onTouchEvent(MotionEvent paramMotionEvent) {
Log.d(TAG, "action = " + (0xFF & paramMotionEvent.getAction()));
if (mHeaderView != null && !isHideHeader && isEnableZoom) {
switch (0xFF & paramMotionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_OUTSIDE:
if (!mScalingRunnable.isFinished()) {
mScalingRunnable.abortAnimation();
}
mLastMotionY = paramMotionEvent.getY();
mActivePointerId = paramMotionEvent.getPointerId(0);
mMaxScale = (mScreenHeight / mHeaderHeight);
mLastScale = (mHeaderContainer.getBottom() / mHeaderHeight);
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "mActivePointerId" + mActivePointerId);
int j = paramMotionEvent.findPointerIndex(mActivePointerId);
if (j == INVALID_VALUE) {
Log.e("PullToZoomListView", "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
} else {
if (mLastMotionY == -1.0F) {
mLastMotionY = paramMotionEvent.getY(j);
}
if (mHeaderContainer.getBottom() >= mHeaderHeight) {
ViewGroup.LayoutParams localLayoutParams = mHeaderContainer.getLayoutParams();
float f = ((paramMotionEvent.getY(j) - mLastMotionY + mHeaderContainer.getBottom()) / mHeaderHeight - mLastScale) / 2.0F + mLastScale;
if ((mLastScale <= 1.0D) && (f < mLastScale)) {
localLayoutParams.height = mHeaderHeight;
mHeaderContainer.setLayoutParams(localLayoutParams);
return super.onTouchEvent(paramMotionEvent);
}
mLastScale = Math.min(Math.max(f, 1.0F), mMaxScale);
localLayoutParams.height = ((int) (mHeaderHeight * mLastScale));
if (localLayoutParams.height < mScreenHeight) {
mHeaderContainer.setLayoutParams(localLayoutParams);
}
mLastMotionY = paramMotionEvent.getY(j);
return true;
}
mLastMotionY = paramMotionEvent.getY(j);
}
break;
case MotionEvent.ACTION_UP:
reset();
endScaling();
break;
case MotionEvent.ACTION_CANCEL:
int i = paramMotionEvent.getActionIndex();
mLastMotionY = paramMotionEvent.getY(i);
mActivePointerId = paramMotionEvent.getPointerId(i);
break;
case MotionEvent.ACTION_POINTER_DOWN:
onSecondaryPointerUp(paramMotionEvent);
mLastMotionY = paramMotionEvent.getY(paramMotionEvent.findPointerIndex(mActivePointerId));
break;
}
}
return super.onTouchEvent(paramMotionEvent);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
trankId = event.getPointerId(event.getActionIndex());
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_POINTER_DOWN:
trankId = event.getPointerId(event.getActionIndex());
int downIndex = event.getActionIndex();
downX = event.getX(downIndex);
downY = event.getY(downIndex);
break;
case MotionEvent.ACTION_MOVE:
int moveIndex = event.findPointerIndex(trankId);
if (moveIndex >= 0) {
mTranX = event.getX(moveIndex) - downX + mTranX;
mTranY = event.getY(moveIndex) - downY + mTranY;
handlerPort();
invalidate();
downX = event.getX(moveIndex);
downY = event.getY(moveIndex);
}
break;
case MotionEvent.ACTION_POINTER_UP:
// 抬起的是当前的手指
if (event.getPointerId(event.getActionIndex()) == trankId && event.getPointerCount() > 1) {
int newIndex;
if (event.getActionIndex() == event.getPointerCount() - 1 && event.getPointerCount() > 2) {
newIndex = event.getActionIndex() - 2;
} else {
newIndex = event.getActionIndex() - 1;
}
if (newIndex >= 0) {
trankId = event.getPointerId(newIndex);
downX = event.getX(newIndex);
downY = event.getY(newIndex);
}
}
break;
}
return true;
}
@SuppressWarnings("deprecation")
synchronized public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
int count = event.getPointerCount();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
downX = eventX;
downY = eventY;
if (count >= 2) {
downX2 = event.getX(1);
downY2 = event.getY(1);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
downX2 = event.getX(1);
downY2 = event.getY(1);
break;
case MotionEvent.ACTION_MOVE:
if (count >= 2) {
// 回転角度の取得
float angle = getAngle(downX, downY, downX2, downY2, eventX, eventY, event.getX(1), event.getY(1));
// 画像の回転
if (angle != SLOPE_0) {
this.angle -= angle * 180d / Math.PI;
}
downX2 = event.getX(1);
downY2 = event.getY(1);
if (rotationGestureListener != null) {
rotationGestureListener.onRotation(this);
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
switch (event.getAction()) {
case MotionEvent.ACTION_POINTER_1_UP:
isFirstPointerUp = true;
break;
default:
}
break;
default:
}
if (isFirstPointerUp) {
downX = downX2;
downY = downY2;
isFirstPointerUp = false;
} else {
downX = eventX;
downY = eventY;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
int action = event.getAction() & MotionEvent.ACTION_MASK;
//最后一个点抬起或者取消,结束所有模式
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
//如果之前是缩放模式,还需要触发一下缩放结束动画
if (mPinchMode == PINCH_MODE_SCALE) {
scaleEnd();
}
mPinchMode = PINCH_MODE_FREE;
} else if (action == MotionEvent.ACTION_POINTER_UP) {
//多个手指情况下抬起一个手指,此时需要是缩放模式才触发
if (mPinchMode == PINCH_MODE_SCALE) {
//抬起的点如果大于2,那么缩放模式还有效,但是有可能初始点变了,重新测量初始点
if (event.getPointerCount() > 2) {
//如果还没结束缩放模式,但是第一个点抬起了,那么让第二个点和第三个点作为缩放控制点
if (event.getAction() >> 8 == 0) {
saveScaleContext(event.getX(1), event.getY(1), event.getX(2), event.getY(2));
//如果还没结束缩放模式,但是第二个点抬起了,那么让第一个点和第三个点作为缩放控制点
} else if (event.getAction() >> 8 == 1) {
saveScaleContext(event.getX(0), event.getY(0), event.getX(2), event.getY(2));
}
}
//如果抬起的点等于2,那么此时只剩下一个点,也不允许进入单指模式,因为此时可能图片没有在正确的位置上
}
//第一个点按下,开启滚动模式,记录开始滚动的点
} else if (action == MotionEvent.ACTION_DOWN) {
//在矩阵动画过程中不允许启动滚动模式
if (!(mScaleAnimator != null && mScaleAnimator.isRunning())) {
//停止所有动画
cancelAllAnimator();
//切换到滚动模式
mPinchMode = PINCH_MODE_SCROLL;
//保存触发点用于move计算差值
mLastMovePoint.set(event.getX(), event.getY());
}
//非第一个点按下,关闭滚动模式,开启缩放模式,记录缩放模式的一些初始数据
} else if (action == MotionEvent.ACTION_POINTER_DOWN) {
//停止所有动画
cancelAllAnimator();
//切换到缩放模式
mPinchMode = PINCH_MODE_SCALE;
//保存缩放的两个手指
saveScaleContext(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
} else if (action == MotionEvent.ACTION_MOVE) {
if (!(mScaleAnimator != null && mScaleAnimator.isRunning())) {
//在滚动模式下移动
if (mPinchMode == PINCH_MODE_SCROLL) {
//每次移动产生一个差值累积到图片位置上
scrollBy(event.getX() - mLastMovePoint.x, event.getY() - mLastMovePoint.y);
//记录新的移动点
mLastMovePoint.set(event.getX(), event.getY());
//在缩放模式下移动
} else if (mPinchMode == PINCH_MODE_SCALE && event.getPointerCount() > 1) {
//两个缩放点间的距离
float distance = MathUtils
.getDistance(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
//保存缩放点中点
float[] lineCenter = MathUtils
.getCenterPoint(event.getX(0), event.getY(0), event.getX(1), event.getY(1));
mLastMovePoint.set(lineCenter[0], lineCenter[1]);
//处理缩放
scale(mScaleCenter, mScaleBase, distance, mLastMovePoint);
}
}
}
//无论如何都处理各种外部手势
mGestureDetector.onTouchEvent(event);
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_DOWN: {
if (event.getPointerCount() == 1) {
if (checkForMoving && !isMoving) {
float locationX = event.getX();
float locationY = event.getY();
lastX = locationX;
lastY = locationY;
if (locationX >= actualArea.x && locationX <= actualArea.x + actualArea.width && locationY >= actualArea.y && locationY <= actualArea.y + actualArea.height) {
isMoving = true;
}
checkForMoving = false;
if (isMoving) {
handlePan(GestureStateBegan, event);
}
}
} else {
if (isMoving) {
handlePan(GestureStateEnded, event);
checkForMoving = true;
isMoving = false;
}
}
break;
}
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
if (isMoving) {
handlePan(GestureStateEnded, event);
isMoving = false;
}
checkForMoving = true;
break;
}
case MotionEvent.ACTION_MOVE: {
if (isMoving) {
handlePan(GestureStateChanged, event);
}
}
}
return true;
}
@Override
public boolean onTouch(View view, MotionEvent event) {
try {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// remove the listener because 'onAnimationEnd' will still be called if we cancel the animation.
this.frame.animate().setListener(null);
this.frame.animate().cancel();
resetAnimCanceled = true;
// Save the ID of this pointer
mActivePointerId = event.getPointerId(0);
final float x = event.getX(mActivePointerId);
final float y = event.getY(mActivePointerId);
// Remember where we started
aDownTouchX = x;
aDownTouchY = y;
// to prevent an initial jump of the magnifier, aposX and aPosY must
// have the values from the magnifier frame
aPosX = frame.getX();
aPosY = frame.getY();
if (y < objectH/2) {
touchPosition = TOUCH_ABOVE;
} else {
touchPosition = TOUCH_BELOW;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
// Extract the index of the pointer that left the touch sensor
final int pointerIndex = (event.getAction() &
MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = event.getPointerId(newPointerIndex);
}
break;
case MotionEvent.ACTION_MOVE:
// Find the index of the active pointer and fetch its position
final int pointerIndexMove = event.findPointerIndex(mActivePointerId);
final float xMove = event.getX(pointerIndexMove);
final float yMove = event.getY(pointerIndexMove);
// from http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html
// Calculate the distance moved
final float dx = xMove - aDownTouchX;
final float dy = yMove - aDownTouchY;
// Move the frame
aPosX += dx;
aPosY += dy;
// calculate the rotation degrees
float distObjectX = aPosX - objectX;
float rotation = BASE_ROTATION_DEGREES * 2f * distObjectX / parentWidth;
if (touchPosition == TOUCH_BELOW) {
rotation = -rotation;
}
// in this area would be code for doing something with the view as the frame moves.
if (isNeedSwipe) {
frame.setX(aPosX);
frame.setY(aPosY);
frame.setRotation(rotation);
mFlingListener.onScroll(getScrollProgress(), getScrollXProgressPercent());
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
//mActivePointerId = INVALID_POINTER_ID;
int pointerCount = event.getPointerCount();
int activePointerId = Math.min(mActivePointerId, pointerCount - 1);
aTouchUpX = event.getX(activePointerId);
mActivePointerId = INVALID_POINTER_ID;
resetCardViewOnStack(event);
break;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getPointerCount() != 2)
return false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN: {
sX = event.getX(0);
sY = event.getY(0);
fX = event.getX(1);
fY = event.getY(1);
}
break;
case MotionEvent.ACTION_MOVE: {
float nfX, nfY, nsX, nsY;
nsX = event.getX(0);
nsY = event.getY(0);
nfX = event.getX(1);
nfY = event.getY(1);
angle = angleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY);
if (mListener != null) {
if (Float.isNaN(startAngle)) {
startAngle = angle;
mListener.onRotationBegin(this);
} else {
mListener.onRotation(this);
}
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
startAngle = Float.NaN;
}
break;
case MotionEvent.ACTION_POINTER_UP: {
startAngle = Float.NaN;
if (mListener != null) {
mListener.onRotationEnd(this);
}
}
break;
}
return true;
}