安卓旋转地图视图

5
我正在创建一个应用程序,该应用程序跟踪用户在地图视图上的路径。例如,当用户向左转时,我想实现地图自动旋转,以使地图视图的头始终指向向上的方向。我希望这有意义。
我看到了Romain Guy先生的帖子,他说:
我过去做过这个,需要创建一个自定义ViewGroup,在dispatchDraw()方法中旋转Canvas。您还需要增加MapView的大小(以便在旋转时绘制足够的像素)。您还需要在dispatchTouchEvent()中旋转触摸事件。或者如果您使用Android 3.0,则可以简单地调用theMapView.rotate() :
有没有人遇到类似于我的问题的解决方案?一个可行的示例将是非常好的 :)

请查看我的答案:在Android中旋转MapView - TouchBoarder
3个回答

8
请记住,这并不是一种理想的方法,因为地图上的文本是静态图像,并且将随着地图瓦片旋转(在某些时候它将颠倒)。
以下是如何将 MapView 放入您自己的 Layout 小部件并旋转它的示例。我已经使用OpenStreetMaps完成了此操作,但对于Google Maps应该是相同的。
首先创建“旋转” Layout 小部件。
package com.eli.util;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.LinearLayout;

public class RotatingLinearLayout extends LinearLayout {

    private final int mDiagonal;
    private float mBearing;

    public RotatingLinearLayout(final Context pContext, final AttributeSet pAttrs) {
        super(pContext, pAttrs);
        final DisplayMetrics dm = pContext.getResources().getDisplayMetrics();
        mDiagonal = (int) Math.hypot(dm.widthPixels, dm.heightPixels);
    }

    public void setBearing(final float pBearing) {
        mBearing = pBearing;
    }

    @Override
    protected void dispatchDraw(final Canvas pCanvas) {
        pCanvas.rotate(-mBearing, getWidth() >> 1, getHeight() >> 1);
        super.dispatchDraw(pCanvas);
    }

    @Override
    protected void onMeasure(final int pWidthMeasureSpec,
            final int pHeightMeasureSpec) {
        final int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);
        super.onMeasure(MeasureSpec.makeMeasureSpec(mDiagonal, widthMode), MeasureSpec.makeMeasureSpec(mDiagonal, heightMode));
    }
}

layout.xml 中将其包围在你的 MapView 中。

<com.eli.util.RotatingLinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/rotating_layout">
    <org.osmdroid.views.MapView
        android:id="@+id/map_view"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"/>
</com.eli.util.RotatingLinearLayout>

现在,每次您收到地理位置修复信息时,请更新旋转布局的方向,并且它应该会转动。

嘿,谢谢你的回答。我使用了你的代码来制作一个旋转布局,它可以工作,但是视图没有居中。我的意思是布局比屏幕大,但它只从右侧和底部超出屏幕。我该如何让RotatingLinearLayout居中? - bughi
@bughi 在dispatchDraw中,您需要使用pCanvas.translate(x,y)来移动画布。然而,如何精确计算x和y我无法说。 - Ridcully

2
这是我用来使视图正确居中的代码。
@Override
protected void dispatchDraw(final Canvas pCanvas) {
    int translateX = mDiagonal / 2 - screenWidth / 2;
    int translateY = mDiagonal / 2 - screenHeight / 2;

    pCanvas.translate(- translateX, - translateY);
    pCanvas.rotate(-mBearing, mDiagonal / 2, mDiagonal / 2);

    super.dispatchDraw(pCanvas);
}

0

您可以在安装Android SDK时找到一个示例

android-sdks/add-ons/addon-google_apis-google_inc_-8/samples/MapDemo

但是也许你需要稍微修改两个方法,以便在触摸事件中获得正确的方向。

private class RotateView extends ViewGroup implements SensorListener {

/* ...  */

    private Matrix invertedMatrix = new Matrix();
    private float[] tempLocation = new float[2];


    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        canvas.rotate(mHeading, getWidth() * 0.5f, getHeight() * 0.5f);
        canvas.getMatrix().invert(invertedMatrix);
        mCanvas.delegate = canvas;
        super.dispatchDraw(mCanvas);
        canvas.restore();
    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        centeringAllowed = false;

        float[] location = tempLocation;
        location[0] = ev.getX();
        location[1] = ev.getY();
        invertedMatrix.mapPoints(location);
        ev.setLocation(location[0], location[1]);
        return super.dispatchTouchEvent(ev);
    }
}

这个类是MapDemo项目的一部分


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接