Monday, 4 November 2019

ImageView canvas drag and zoom (by pivot) do not work together

I'm trying to create an application in which the user can drag and zoom an ImageView. But I'm experiencing problems with the following code.

When the scaleFactor is not 1 and I change to 2 fingers or from 2 fingers back to 1 finger it is translated a little to somewhere else. I don't know where this translate comes from...

Here's the onTouchEvent code:

@Override
public boolean onTouchEvent(MotionEvent event) {
    mScaleDetector.onTouchEvent(event);

    int action = event.getActionMasked();

    switch (action) {
        case MotionEvent.ACTION_DOWN: {
            int pointerIndex = event.getActionIndex();
            float x = event.getX(pointerIndex);
            float y = event.getY(pointerIndex);

            // Remember where we started (for dragging)
            mLastTouch = new PointF(x, y);

            // Save the ID of this pointer (for dragging)
            mActivePointerId = event.getPointerId(0);
        }

        case MotionEvent.ACTION_POINTER_DOWN: {
            if (event.getPointerCount() == 2) {
                mLastFocus = new PointF(mScaleDetector.getFocusX(), mScaleDetector.getFocusY());
            }
        }

        case MotionEvent.ACTION_MOVE: {
            // Find the index of the active pointer and fetch its position
            int pointerIndex = event.findPointerIndex(mActivePointerId);

            float x = event.getX(pointerIndex);
            float y = event.getY(pointerIndex);


            if (event.getPointerCount() == 1) {               // TRANSLATE
                // Calculate the distance moved
                float dx = x - mLastTouch.x;
                float dy = y - mLastTouch.y;

                mPosX += dx;
                mPosY += dy;

                matrix.setScale(scaleFactor, scaleFactor, mLastFocus.x, mLastFocus.y);
                matrix.postTranslate(mPosX, mPosY);

                // Remember this touch position for the next move event
                mLastTouch = new PointF(x, y);
            } else if (event.getPointerCount() == 2) {                                            // SCALE
                // Calculate the distance moved
                float dx = mScaleDetector.getFocusX() - mLastFocus.x;
                float dy = mScaleDetector.getFocusY() - mLastFocus.y;

                mPosX += dx;
                mPosY += dy;

                matrix.setScale(scaleFactor, scaleFactor, -mPosX + mScaleDetector.getFocusX(), -mPosY + mScaleDetector.getFocusY());
                matrix.postTranslate(mPosX, mPosY);

                // Remember this touch position for the next move event
                mLastFocus = new PointF(mScaleDetector.getFocusX(), mScaleDetector.getFocusY());
            }

            break;
        }

        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = event.getActionIndex();
            final int pointerId = event.getPointerId(pointerIndex);

            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouch = new PointF(event.getX(newPointerIndex), event.getY(newPointerIndex));
                mActivePointerId = event.getPointerId(newPointerIndex);
            } else {
                final int tempPointerIndex = event.findPointerIndex(mActivePointerId);
                mLastTouch = new PointF(event.getX(tempPointerIndex), event.getY(tempPointerIndex));
            }

            break;
        }
    }

    invalidate();
    return true;
}


from ImageView canvas drag and zoom (by pivot) do not work together

No comments:

Post a Comment