How to fix pinch zoom focal point in a custom view?

旧时模样 提交于 2019-12-03 12:46:30

Using Matrix is a really better idea - the code is much more simple and you dont have to prove your math skills ;-), see how Matrix#postTranslate and Matrix#postScale methods are used:

class MyView extends View {
    private static final String TAG = "MyView";

    private final ScaleGestureDetector mScaleDetector;
    private final GestureDetector mGestureDetector;

    private final Drawable mBoard;
    private final float mBoardWidth;
    private final float mBoardHeight;
    private Matrix mMatrix;

    public MyView(Context context) {
        this(context, null, 0);
    }

    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mBoard = ResourcesCompat.getDrawable(context.getResources(), R.drawable.chrome, null);
        mBoardWidth = mBoard.getIntrinsicWidth();
        mBoardHeight = mBoard.getIntrinsicHeight();
        mBoard.setBounds(0, 0, (int) mBoardWidth, (int) mBoardHeight);

        mMatrix = new Matrix();

        mScaleDetector = new ScaleGestureDetector(context, scaleListener);
        mGestureDetector = new GestureDetector(context, listener);
    }

    ScaleGestureDetector.OnScaleGestureListener scaleListener = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
        @Override
        public boolean onScale(ScaleGestureDetector scaleDetector) {
            float factor = scaleDetector.getScaleFactor();
            mMatrix.postScale(factor, factor, getWidth() / 2f, getHeight() / 2f);
            ViewCompat.postInvalidateOnAnimation(MyView.this);
            return true;
        }
    };

    GestureDetector.OnGestureListener listener = new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float dX, float dY) {
            mMatrix.postTranslate(-dX, -dY);
            ViewCompat.postInvalidateOnAnimation(MyView.this);
            return true;
        }
    };

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        float scale = Math.max(w / mBoardWidth, h / mBoardHeight);
        mMatrix.setScale(scale, scale);
        mMatrix.postTranslate((w - scale * mBoardWidth) / 2f, (h - scale * mBoardHeight) / 2f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.concat(mMatrix);
        mBoard.draw(canvas);
        canvas.restore();
    }

    @Override
    @SuppressLint("ClickableViewAccessibility")
    public boolean onTouchEvent(MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        mScaleDetector.onTouchEvent(e);
        return true;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!