mercredi 6 mai 2015

Android scaling/transforming canvas doesn't modify clickable area

I'm having a very similar issue described here, except instead of using ScaleAnimation, I'm allowing pinch zoom/pan in my RelativeLayout.

The zoom/panning works perfectly, but regardless of how my view is panned/zoomed, the clickable area does not change along with the visual representation. Here's what my dispatchTouchEvent looks like:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (mScaleGestureDetector != null && mGestureDetector != null) {
        mScaleGestureDetector.onTouchEvent(ev);
        mGestureDetector.onTouchEvent(ev);
    }

    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: {
            final float x = ev.getX();
            final float y = ev.getY();

            mLastTouchX = x;
            mLastTouchY = y;
            mActivePointerId = ev.getPointerId(0);
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float y = ev.getY(pointerIndex);

            // Only move if the ScaleGestureDetector isn't processing a gesture.
            if (!mScaleGestureDetector.isInProgress() && mScaleFactor > 1f) {
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                float newPosX = mPosX + dx;
                float newPosY = mPosY + dy;
                if (isCoordinateInBound(newPosX, mScreenSize.x))
                    mPosX = newPosX;
                if (isCoordinateInBound(newPosY, mScreenSize.y))
                    mPosY = newPosY;

                invalidate();
            }

            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

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

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

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = ev.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = ev.getX(newPointerIndex);
                mLastTouchY = ev.getY(newPointerIndex);
                mActivePointerId = ev.getPointerId(newPointerIndex);
            }
            break;
        }
    }

    return super.dispatchTouchEvent(ev);
}

and my dispatchDraw:

protected void dispatchDraw(Canvas canvas) {
    canvas.save(Canvas.MATRIX_SAVE_FLAG);
    canvas.translate(mPosX, mPosY);

    canvas.scale(mScaleFactor, mScaleFactor);
    super.dispatchDraw(canvas);
    canvas.restore();
}

How do you modify the clickable area accordingly to modified scale/transformation of canvas?

Aucun commentaire:

Enregistrer un commentaire