예제 #1
0
  @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;
  }