Implementing pinch zoom and drag using Android's build in gesture listener and scale listener

后端 未结 1 1607
自闭症患者
自闭症患者 2020-12-04 13:30

I am trying to implement pinch zoom and drag using Android\'s gesture listener and scale listener. The problem is that when I perform pinch zoom, the image (which I am tryin

相关标签:
1条回答
  • 2020-12-04 14:09

    I have implemented this behaviour, and I used a matrix to handle all the zooming and scrolling (and rotation, in my case). It makes for neat code and works like clockwork.

    Store a Matrix as a class member:

    Matrix drawMatrix;
    

    Edit: Store old focus point, used to get the focus shift during scaling.

    float lastFocusX;
    float lastFocusY;
    

    Edit: Set lastFocus variables in onScaleBegin

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        lastFocusX = detector.getFocusX();
        lastFocusY = detector.getFocusY();
        return true;
    }
    

    Replace your onScale:

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        Matrix transformationMatrix = new Matrix();
        float focusX = detector.getFocusX();
        float focusY = detector.getFocusY();
    
        //Zoom focus is where the fingers are centered, 
        transformationMatrix.postTranslate(-focusX, -focusY);
    
        transformationMatrix.postScale(detector.getScaleFactor(), detector.getScaleFactor());
    
    /* Adding focus shift to allow for scrolling with two pointers down. Remove it to skip this functionality. This could be done in fewer lines, but for clarity I do it this way here */
        //Edited after comment by chochim
        float focusShiftX = focusX - lastFocusX;
        float focusShiftY = focusY - lastFocusY;
        transformationMatrix.postTranslate(focusX + focusShiftX, focusY + focusShiftY);
        drawMatrix.postConcat(transformationMatrix);
        lastFocusX = focusX;
        lastFocusY = focusY;
        invalidate();
        return true;
    }
    

    Similarly in onScroll:

    @Override
    public boolean onScroll(MotionEvent downEvent, MotionEvent currentEvent,
                float distanceX, float distanceY) {
        drawMatrix.postTranslate(-distanceX, -distanceY);
        invalidate();
        return true;
    }
    

    in onDraw; Draw with your drawMatrix:

    canvas.drawBitmap(image, drawMatrix, paint);
    

    Happy coding!

    0 讨论(0)
提交回复
热议问题