3

我的自定义视图中有一个背景图像作为可绘制对象。这个drawable可以被缩放或移动。

目前我需要一个在图像上绘制的绿点相对于屏幕是静止的。也就是说,它应该始终与销位于相同的位置,如下所示。(当然,图钉只是一个 ImageView,根本不动!)

在此处输入图像描述

后面的地图在我的自定义视图 MapView 中按如下方式移动时,我已成功使其相对于屏幕静止:

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Let the ScaleGestureDetector inspect all events.
        mScaleDetector.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: { // triggered as long as finger movers
            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 (!mScaleDetector.isInProgress()) {
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                // update the starting point if the 'Start' button is not yet pressed
                // to ensure the screen center (i.e. the pin) is always the starting point
                if (!isStarted) {
                    Constant.setInitialX(Constant.INITIAL_X - dx);
                    Constant.setInitialY(Constant.INITIAL_Y - dy);
                    if ((historyXSeries.size() > 0) && (historyYSeries.size() > 0)) {
                        // new initial starting point
                        historyXSeries.set(0, Constant.INITIAL_X);
                        historyYSeries.set(0, Constant.INITIAL_Y);
                    }
                }

                invalidate();
            }

            mLastTouchX = x;
            mLastTouchY = y;

            break;
        }

通过上面的操作,当背景图像移动时,我的绿点会停留在那里。

但是当背景图像被缩放时,我在试图让它保持在那里时遇到了问题。

本质上,我并不真正了解其canvas.scale(mScaleFactor, mScaleFactor)工作原理,因此我无法像在简单移动案例中所做的那样相应地移动绿点。

我认为应该在下面的比例监听器处理程序中添加一些东西,有人可以帮我填写那部分吗?

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            mScaleFactor *= detector.getScaleFactor();

            // Don't let the object get too small or too large.
            mScaleFactor = Math.max(1f, Math.min(mScaleFactor, 10.0f)); // 1 ~ 10

            // HOW TO MOVE THE GREEN DOT HERE??

            invalidate();
            return true;
        }

或者请至少解释一下是如何canvas.scale(mScaleFactor, mScaleFactor)工作的,我该如何相应地移动绿点?

4

1 回答 1

1

请记住,画布被认为可以根据比例因子缩放所有内容,因此虽然可以反对缩放,但这可能不是最好的方法。但是,如果这是您正在寻找的,我会尽我所能帮助您。

我假设以下内容:

  • 比例因子是相对于当前缩放的(旧缩放总是比例因子 1)。如果不是这种情况,那么您应该在缩放大约 200% 两次后观察缩放值,并查看生成的缩放因子是 4 还是 3(指数或线性)。例如,对于 200% 的缩放因子,您可以通过将比例因子标准化为 2 来实现以下结果。您必须记住旧的比例因子才能这样做。
  • 不进行旋转

如果是这种情况,那么对于缩放中心的标记可以说跟随。

对于缩放后远离缩放中心的 每个水平像素xzoom_center_x + *x* / scale_factor ,其原始位置可以计算为:(或替代zoom_center_x + (marker_x - zoom_center_x) / scale_factor)。换句话说,如果缩放中心是(50, 0)并且标记(100, 0)的比例因子为2,那么x位置很50 + (100 - 50) / 2 or 75. 明显,如果标记在缩放中心的同一位置,那么x位置将与缩放中心相同。同样,如果比例为1,那么标记的x位置会和现在一样。

这同样适用于 y 轴。

虽然我无法确切知道如何设置标记的位置,但我希望代码看起来像:

Point zoomCenter = detector.getZoomCenter();
// Set marker variable here
marker.setX(Math.round(zoomCenter.getX() + ((double)(marker.getX() - zoomCenter.getX())) / mScaleFactor));
marker.setY(Math.round(zoomCenter.getY() + ((double)(marker.getY() - zoomCenter.getY())) / mScaleFactor));

我希望这会有所帮助。

于 2013-07-10T10:29:25.980 回答