Android 如何从视图中心点更改视图的上边缘和左边缘缩放布局

Android 如何从视图中心点更改视图的上边缘和左边缘缩放布局,android,android-layout,zooming,pinchzoom,Android,Android Layout,Zooming,Pinchzoom,我想在布局中拖动和缩放视图我已经实现了拖动和缩放,但我的问题是,当我缩放视图时,它会以非常快的方式缩放,我已经尝试了很多次,我认为我计算的sacle因子错误,或者给出了错误的左视图和上视图边距 public class ZoomLayout extends RelativeLayout { private static final int NONE = 0; private static final int DRAG = 1; private static final int Z

我想在布局中拖动和缩放视图我已经实现了拖动和缩放,但我的问题是,当我缩放视图时,它会以非常快的方式缩放,我已经尝试了很多次,我认为我计算的sacle因子错误,或者给出了错误的左视图和上视图边距

public class ZoomLayout extends RelativeLayout  {

  private static final int NONE = 0;
  private static final int DRAG = 1;
  private static final int ZOOM = 2;
  private int mode = NONE;
  // remember some things for zooming
  private PointF start = new PointF();
  private PointF mid = new PointF();
  private float oldDist = 1f;
  private float d = 0f;
  private static final String TAG = "ZoomLayout";
  private static final float MIN_ZOOM = 1.0f;
  private static final float MAX_ZOOM = 4.0f;


  private float scale = 1.0f;
  private float lastScaleFactor = 0f;

  // Where the finger first  touches the screen
  private float startX = 0f;
  private float startY = 0f;

  private int _xDelta;
  private int _yDelta;

  // How much to translate the canvas
  private float dx = 0f;
  private float dy = 0f;
  private float prevDx = 0f;
  private float prevDy = 0f;

  public ZoomLayout(Context context) {
    super(context);
    init(context);
  }

  public ZoomLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
  }

  public ZoomLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
  }

  private void init(Context context) {

    this.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View view, MotionEvent event) {
          int dx = 0,dy = 0;
          switch (event.getAction() & MotionEvent.ACTION_MASK) {
          case MotionEvent.ACTION_DOWN:
              savedMatrix.set(matrix);
              start.set(event.getX(), event.getY());
              mode = DRAG;
              RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) child().getLayoutParams();
                _xDelta =(int) (event.getX()  - lParams.leftMargin);
                _yDelta = (int) (event.getY() - lParams.topMargin);
              lastEvent = null;
              break;
          case MotionEvent.ACTION_POINTER_DOWN:
              oldDist = spacing(event);
              if (oldDist > 10f) {
                  RelativeLayout.LayoutParams l0Params = (RelativeLayout.LayoutParams) child().getLayoutParams();
                    dx = (int) (l0Params.leftMargin);
                    dy = (int) (l0Params.topMargin);
                  mode = ZOOM;
              }

              break;
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_POINTER_UP:
              mode = NONE;
              lastEvent = null;
              break;
          case MotionEvent.ACTION_MOVE:
              if (mode == DRAG) {

                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) child()
                .getLayoutParams();
                layoutParams.leftMargin = (int) (event.getX() - _xDelta);
                layoutParams.topMargin =(int) (event.getY() - _yDelta);
                layoutParams.rightMargin = -250;
                layoutParams.bottomMargin = -250;
                child().setLayoutParams(layoutParams);

              } else if (mode == ZOOM) {
                  float newDist = spacing(event);
                  if (newDist > 10f) {
                     // matrix.set(savedMatrix);
                      float scale = (newDist / oldDist);
                     // matrix.pos
                      //matrix.postScale(scale, scale, mid.x, mid.y);
                      LayoutParams layoutParams=(RelativeLayout.LayoutParams) child().getLayoutParams();
                      layoutParams.leftMargin= (int) (child().getWidth()*scale*layoutParams.leftMargin)/child().getWidth();//(layoutParams.leftMargin - dx);
                      layoutParams.topMargin = (int) (child().getHeight()*scale*layoutParams.topMargin)/child().getWidth();//(layoutParams.topMargin - dy);
                      layoutParams.height=(int) (child().getHeight()*scale);
                      layoutParams.width=(int) (child().getWidth()*scale);
                      child().setLayoutParams(layoutParams);
                  }

              }
              break;
      }

      //gifDrawable.setMatrix(matrix); 
      return true;
  }

    });
  }

  /**
   * Determine the space between the first two fingers
   */
  private float spacing(MotionEvent event) {
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return (float)Math.sqrt(x * x + y * y);
  }

  /**
   * Calculate the mid point of the first two fingers
   */
  private void midPoint(PointF point, MotionEvent event) {
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
  }

  /**
   * Calculate the degree to be rotated by.
   *
   * @param event
   * @return Degrees
   */
  private float rotation(MotionEvent event) {
      double delta_x = (event.getX(0) - event.getX(1));
      double delta_y = (event.getY(0) - event.getY(1));
      double radians = Math.atan2(delta_y, delta_x);
      return (float) Math.toDegrees(radians);
  }
  // ScaleGestureDetector

  @Override
  public boolean onScaleBegin(ScaleGestureDetector scaleDetector) {
    Log.i(TAG, "onScaleBegin");
    return true;
  }

  @Override
  public boolean onScale(ScaleGestureDetector scaleDetector) {
        return true;
  }

  @Override
  public void onScaleEnd(ScaleGestureDetector scaleDetector) {
    Log.i(TAG, "onScaleEnd");
  }


  private View child() {
    return getChildAt(0);
  }
}
我已经尝试了很多方法,但每当我缩放视图时,它都会缩放得非常快,所以请建议我如何在视图上实现最佳缩放效果