Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android-Pinch可缩放的Android框架布局_Java_Android_Zooming - Fatal编程技术网

Java Android-Pinch可缩放的Android框架布局

Java Android-Pinch可缩放的Android框架布局,java,android,zooming,Java,Android,Zooming,我过去常常执行收缩缩放和拖动 public class ZoomLayout extends FrameLayout implements ScaleGestureDetector.OnScaleGestureListener { private enum Mode { NONE, DRAG, ZOOM } private static final String TAG = "ZoomLayout"; private static final floa

我过去常常执行收缩缩放和拖动

public class ZoomLayout extends FrameLayout implements ScaleGestureDetector.OnScaleGestureListener {

  private enum Mode {
    NONE,
    DRAG,
    ZOOM
  }

  private static final String TAG = "ZoomLayout";
  private static final float MIN_ZOOM = 1.0f;
  private static final float MAX_ZOOM = 4.0f;

  private Mode mode = Mode.NONE;
  private float scale = 1.0f;
  private float lastScaleFactor = 0f;

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

  // 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) {
    final ScaleGestureDetector scaleDetector = new ScaleGestureDetector(context, this);
    this.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
          case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "DOWN");
            if (scale > MIN_ZOOM) {
              mode = Mode.DRAG;
              startX = motionEvent.getX() - prevDx;
              startY = motionEvent.getY() - prevDy;
            }
            break;
          case MotionEvent.ACTION_MOVE:
            if (mode == Mode.DRAG) {
              dx = motionEvent.getX() - startX;
              dy = motionEvent.getY() - startY;
            }
            break;
          case MotionEvent.ACTION_POINTER_DOWN:
            mode = Mode.ZOOM;
            break;
          case MotionEvent.ACTION_POINTER_UP:
            mode = Mode.DRAG;
            break;
          case MotionEvent.ACTION_UP:
            Log.i(TAG, "UP");
            mode = Mode.NONE;
            prevDx = dx;
            prevDy = dy;
            break;
        }
        scaleDetector.onTouchEvent(motionEvent);

        if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) {
          getParent().requestDisallowInterceptTouchEvent(true);
          float maxDx = (child().getWidth() - (child().getWidth() / scale)) / 2 * scale;
          float maxDy = (child().getHeight() - (child().getHeight() / scale))/ 2 * scale;
          dx = Math.min(Math.max(dx, -maxDx), maxDx);
          dy = Math.min(Math.max(dy, -maxDy), maxDy);
          Log.i(TAG, "Width: " + child().getWidth() + ", scale " + scale + ", dx " + dx
            + ", max " + maxDx);
          applyScaleAndTranslation();
        }

        return true;
      }
    });
  }

  // ScaleGestureDetector

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

  @Override
  public boolean onScale(ScaleGestureDetector scaleDetector) {
    float scaleFactor = scaleDetector.getScaleFactor();
    Log.i(TAG, "onScale" + scaleFactor);
    if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) {
      scale *= scaleFactor;
      scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));
      lastScaleFactor = scaleFactor;
    } else {
      lastScaleFactor = 0;
    }
    return true;
  }

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

  private void applyScaleAndTranslation() {
    child().setScaleX(scale);
    child().setScaleY(scale);
    child().setTranslationX(dx);
    child().setTranslationY(dy);
  }

  private View child() {
    return getChildAt(0);
  }
}
我的问题是,当我放大,然后拖动时,它会捕捉到屏幕的中间。我认为问题在于:

case MotionEvent.ACTION_DOWN:
            Log.i(TAG, "DOWN");
            if (scale > MIN_ZOOM) {
              mode = Mode.DRAG;
              startX = motionEvent.getX() - prevDx;
              startY = motionEvent.getY() - prevDy;
            }
            break;

我不知道如何解决这个问题,有人能帮我吗?

我通过将
onScale
更改为:

public boolean onScale(ScaleGestureDetector scaleDetector) {
        float scaleFactor = scaleDetector.getScaleFactor();
        Log.i(TAG, "mode:" + this.mode + ", onScale:" + scaleFactor);
        if (this.lastScaleFactor == 0.0f || Math.signum(scaleFactor) == Math.signum(this.lastScaleFactor)) {
            this.scale *= scaleFactor;
            this.scale = Math.max(MIN_ZOOM, Math.min(this.scale, MAX_ZOOM));
            this.lastScaleFactor = scaleFactor;
        } else {
            this.lastScaleFactor = 0.0f;
        }
        if (this.mSurfaceView != null) {
            int orgWidth = getWidth();
            int _width = (int) (((float) orgWidth) * this.scale);
            int _height = (int) (((float) getHeight()) * this.scale);
            LogUtil.b(new StringBuilder(String.valueOf(_width)).append(", ").append(_height).toString());
            LayoutParams params = (LayoutParams) this.mSurfaceView.getLayoutParams();
            params.height = _height;
            params.width = _width;
            this.mSurfaceView.setLayoutParams(params);
            child().setScaleX(this.scale);
            child().setScaleY(this.scale);
        }
        return true;
    }

为什么不使用
手势检测器
scalegestruedetector
?@pskink感谢您的贡献,但我已经修复了它。
mSurfaceView
未定义。