首页 文章

ANDROID - MapView

提问于
浏览
2

有人可以帮我一些关于mapview我试图 Build 的东西 . 我有一个渲染器,它采用画布并在其中绘制位图 . 我创建了一个视图,并在构造函数中创建:

bitmap = Bitmap.createBitmap(windowWidth, windowHeight, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
drawable = new BitmapDrawable(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
this.Render();

在onDraw方法中我有这个:

super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
drawable.draw(canvas);
canvas.restore();

现在我想实现平移和缩放(目前即时工作没有保存的瓷砖)这是我的onTouch:

mScaleDetector.onTouchEvent(EV);

final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_DOWN: {
    this.hasPanned = false;
    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);

    if (!mScaleDetector.isInProgress()) {
        final float dx = x - mLastTouchX;
        final float dy = y - mLastTouchY;

        mPosX += dx;
        mPosY += dy;

        invalidate();
    }

    mLastTouchX = x;
    mLastTouchY = y;

    break;
}

case MotionEvent.ACTION_UP: {
    mActivePointerId = INVALID_POINTER_ID;
    if (this.mDownTouchX != this.mLastTouchX && this.mDownTouchY != mLastTouchY)
        this.hasPanned = true;
    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 true;

这是我想要的和我遇到的问题:

  • 当我平移时我想计算距离(以像素为单位),以便我可以告诉我的渲染器何时再次渲染图像 . 这是如何实现的?通过记住ACTION_DOWN上的坐标并与ACTION_UP中的新坐标进行比较?

  • 当平移完成(并重新渲染图像)时,我想将画布(图像)设置回原始位置 . 目前它保持paned(因为canvas.translate?)

  • 如何处理缩放手势?用我的手指进行缩小时,使用此代码,图像朝向左上角"dragged"

我是android(和java)的新手,所以任何帮助都是精确的 .

2 回答

  • 2

    1)是的,在ACTION_DOWN中就行了

    PontF downAt = new PointF(event.getX(), event.getY());
    

    并在ACTION_UP中计算像素之间的差异 .

    2)MapView与ImageView的工作方式不同 . 对于您将使用的MapView

    mapView.getController().animateTo(GeoPoint);
    

    但我认为你真的想从ImageView继承并覆盖onDraw(Canvas canvas)方法来直接访问Canvas . 然后使用矩阵处理翻译和缩放,例如

    imageView.setScaleType(ImageView.ScaleType.MATRIX);
    Matrix imageMatrix = new Matrix();
    imageMatrix.postTranslate(xMove, yMove);
    imageMatrix.postScale(scaleX, scaleY, midX, midY);
    imageView.setImageMatrix(imageMatrix);
    

    3)要处理ZOOM手势,您需要处理ACTION_POINTER_DOWN,ACTION_MOVE和ACTION_POINTER_UP事件 . 这里有一个非常好的教程 - How to use Multi-touch in Android

    当你放大一个imageView时要小心,任何后续的绘图需要X,Y坐标也要缩放,使用Matrix mapPoints(Pts)方法来做到这一点 .

  • 1

    如果您的缩放代码缩放了Canvas但没有正确移动它,我怀疑您正在调用错误的Canvas.scale()方法 . 你正在使用的方法似乎是 -

    scale(float sx, float sy)
    

    而且我认为你需要使用 -

    scale(float sx, float sy, float px, float py)
    

    sx&sy显然是x&y比例因子(我通常将它们设置为相同的值) . px&py是缩放操作的中心点,例如MotionEvent.ACTION_DOWN和MotionEvent.ACTION_POINTER_DOWN事件坐标之间的中间点 .

    在我的MotionEvent.ACTION_POINTER_DOWN处理程序中,我调用 -

    midPoint(mid, event);
    

    mid被定义为 -

    private PointF mid = new PointF();
    

    和midPoint功能是 -

    private void midPoint(PointF point, MotionEvent event) 
    {
       float x = event.getX(0) + event.getX(1);
       float y = event.getY(0) + event.getY(1);
       point.set(x / 2, y / 2);
    }
    

    所以在我的MotionEvent.ACTION_MOVE处理程序中我会调用 -

    Canvas.scale(sx, sy, mid.x, mid.y);
    

相关问题