@Override public boolean onTouchEvent(MotionEvent event) { boolean handled = true; switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { // 删除按钮接收事件 if (mShowDashBorder && mDelDrawRectF.contains(event.getX(), event.getY())) { if (getParent() instanceof ViewGroup) { ((ViewGroup) getParent()).removeView(DashFrameLayout.this); } break; } // 拖放按钮接收事件 if (mShowDashBorder && mDragDrawRectF.contains(event.getX(), event.getY())) { mode = SINGLE_ZOOM; showDashBorder(true); mPreDistance = Utils.calcDistance(mCenterPoint[0], mCenterPoint[1], event.getX(), event.getY()); mPreRotation = Utils.calcRotation(mCenterPoint[0], mCenterPoint[1], event.getX(), event.getY()); break; } /** 判断虚线框是否接收事件; 因旋转后无法直接判断事件是否在rect内, 可将坐标点反向旋转后再与未进行旋转的rect进行比较判断 */ mDashDrawRectF.set(mDashRectF); mViewNoRotateMatrix.mapRect(mDashDrawRectF); Matrix inverseMatrix = new Matrix(); // 获取反向旋转矩阵 inverseMatrix.postRotate(360 - mCurRotation, mCenterPoint[0], mCenterPoint[1]); // 将当前坐标反向旋转,再进行判断 float[] eventPoint = {event.getX(), event.getY()}; inverseMatrix.mapPoints(eventPoint); if (mDashDrawRectF.contains(eventPoint[0], eventPoint[1])) { mode = DRAG; mInitTouchX = event.getX(); mInitTouchY = event.getY(); mLastTouchX = event.getX(); mLastTouchY = event.getY(); } else { handled = false; } showDashBorder(handled); if (handled && mListener != null) { mListener.onFocus(); mAlwaysInTapRegion = true; } break; } case MotionEvent.ACTION_MOVE: { if (mAlwaysInTapRegion) { float deltaX = event.getX() - mInitTouchX; float deltaY = event.getY() - mInitTouchY; // 判断是否在点击区域内 if ((deltaX * deltaX) + (deltaY * deltaY) > mTouchSlopSquare) { mAlwaysInTapRegion = false; } } if (mode == SINGLE_ZOOM || mode == DOUBLE_ZOOM) { float curDistance, endRotation; if (mode == SINGLE_ZOOM) { // 单指缩放、旋转 curDistance = Utils.calcDistance(mCenterPoint[0], mCenterPoint[1], event.getX(), event.getY()); endRotation = Utils.calcRotation(mCenterPoint[0], mCenterPoint[1], event.getX(), event.getY()); } else { // 双指缩放、旋转 curDistance = Utils.calcDistance(event); endRotation = Utils.calcRotation(event); } scale(curDistance / mPreDistance); mPreDistance = curDistance; rotate(endRotation - mPreRotation); mPreRotation = endRotation; } else if (mode == DRAG) { translate(event.getX() - mLastTouchX, event.getY() - mLastTouchY); mLastTouchX = event.getX(); mLastTouchY = event.getY(); } invalidate(); break; } case MotionEvent.ACTION_POINTER_DOWN: { mAlwaysInTapRegion = false; if (mode != SINGLE_ZOOM) { mode = DOUBLE_ZOOM; mPreDistance = Utils.calcDistance(event); mPreRotation = Utils.calcRotation(event); } break; } case MotionEvent.ACTION_UP: { mode = NONE; mPreRotation = 0.f; if (mAlwaysInTapRegion && mPreShowDashBorder && mListener != null) { mListener.onClick(); } mAlwaysInTapRegion = false; break; } case MotionEvent.ACTION_POINTER_UP: { if (mode != SINGLE_ZOOM) { mode = NONE; mPreRotation = 0.f; } break; } } return handled; }