缩放问题和 Canvas 使用 ScaleGestureDetector

Issues with zoom and Canvas using ScaleGestureDetector

我正在尝试在我的应用程序中实现缩放。但是我遇到了困难。

到目前为止我做了什么:

(注意:此应用程序是一款游戏,因此它不使用 invalidate,而是使用线程)

渲染和缩放:

public void render(Canvas c) {
    super.draw(c);

    if (c != null) {
        int ss = c.getSaveCount();
        c.scale(scaleFactor, scaleFactor);
        //Rendering stuff
        c.restoreToCount(ss);
    }
}

当前缩放:

(当有两个指针时,这是从 master class 中的 onTouchEvent 调用的。这些 classes 是嵌套的。)

class scaler extends ScaleGestureDetector {
    public scaler(Context context, OnScaleGestureListener listener) {
        super(context, listener);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        listener.onScale(this);
        return super.onTouchEvent(event);
    }

    @Override
    public float getScaleFactor() {
        return super.getScaleFactor();
    }
}
float startScale;
float endScale;
class ScaleListener implements ScaleGestureDetector.OnScaleGestureListener{


        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            startScale = detector.getScaleFactor();
            scaleFactor *= detector.getScaleFactor();
            scaleFactor = (scaleFactor < 1 ? 1 : scaleFactor); // prevent our view from becoming too small //
            scaleFactor = ((float)((int)(scaleFactor * 100))) / 100; // Change precision to help with jitter when user just rests their fingers //
            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {

        }


}

我一直在寻找关于 SO 的几个问题,但我发现的所有问题都无法正常工作。解决方案有多种原因。

我目前使用的:

Zoom in before zooming(比例因子在缩小前下降)
它不会放大手指所在的区域。

那么我怎样才能添加缩放以放大手指所在的区域,并制作它以便在不重置缩放的情况下进行缩放以使其真正放大?

感谢@pskink,这是我解决问题的方法:

  1. 不要覆盖 class 扩展 ScaleGestureDetector 中的 onTouchEvent,也不要调用 OnScaleGestureListener.onScale,因为它是由检测器自动完成的。

这解决了我在缩放方面遇到的问题。

至于放大特定区域,我不得不放弃使用 .setScale,而是使用矩阵:

public void render(Canvas c) {
    super.draw(c);

    if (c != null) {

        c.setMatrix(scaleMatrix);//scale

        //Null the matrix = set to default. 
        c.setMatrix(null);//Past this line, anything rendered is not scaled. 

    }
}

(GestureDetector 不应覆盖 onTouchEvent 并调用侦听器)

在监听器中:

    public boolean onScale(ScaleGestureDetector detector) {
        startScale = detector.getScaleFactor();
        scaleFactor *= detector.getScaleFactor();

        if(scaleFactor > 2) scaleFactor = 2;//Limit max
        else if(scaleFactor < 0.3f) scaleFactor = 0.3f;//limit min
        scaleFactor = ((float)((int)(scaleFactor * 100))) / 100;//jitter-protection
        scaleMatrix.setScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());//setScale, as I don't need to scale several things. 

        return true;
    }