java - Android 缩放/转换 Canvas 不会修改可点击区域

标签 java android canvas

我有一个非常相似的问题 described here ,除了不使用 ScaleAnimation,我允许在我的 RelativeLayout 中捏缩放/平移。

缩放/平移效果完美,但无论我的 View 如何平移/缩放,可点击区域都不会随着视觉表示而改变。这是我的 dispatchTouchEvent 的样子:

@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);
}

和我的 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();
}

如何根据 Canvas 的修改比例/变换修改可点击区域?

最佳答案

因为你已经在覆盖dispatchTouchEvent,你可以试试这个:

  1. 通过考虑当前的缩放/平移转换手动评估每个 MotionEvent;您可以通过对原始 MotionEvent m.
  2. 检查FakeMotionEvent是否拦截一个特定的View v;这意味着用户正在触摸代表 v 的用户可见位置的位置。
  3. 如果 FakeMotionEvent 拦截了 v,消耗当前的 MotionEvent 并调用 v.dispatchTouchEvent(m);

提示:您可以使用下面的方法来评估 MotionEvent 是否以一定的容忍度拦截 View:

private boolean intercept(MotionEvent ev, View view, float boundingBoxTolerance){
    if (boundingBoxTolerance < 1.0f) {
        boundingBoxTolerance = 1.0f;
    }
    try {
        if (ev != null && view != null) {
            int coords[] = new int[2];
            view.getLocationOnScreen(coords);
            if (ev.getRawX() >= ((float)coords[0]) / boundingBoxTolerance && ev.getRawX() <= coords[0] + ((float) view.getWidth()) * boundingBoxTolerance) {
                if(ev.getRawY() >= ((float)coords[1]) / boundingBoxTolerance && ev.getRawY() <= coords[1] + ((float) view.getHeight()) * boundingBoxTolerance)
                    return true;
            }
        }
    }
    catch (Exception e) {}
    return false;
}

关于java - Android 缩放/转换 Canvas 不会修改可点击区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30035642/

相关文章:

java - Android:无法解析自定义 PagerAdapter 中的方法

java - Spring Batch 异步处理器配置以获得最佳性能

java - YouTube 视频 Activity

android - Service中的ImageView没有被WindowManager移除

android - 从 Android 相机 Surface 获取 RGB 值

javascript - 在 JSFiddle 中单击“运行”后代码突然运行。什么?

java - IntelliJ 未检测到同一 Hybris 模块中的 java 类

android - Kotlin 中的接口(interface)作为函数

Android - 通过软键盘输入在 Canvas 上绘制文本

javascript视频 Canvas