2011-05-17 98 views
5

我正在创建一个应用程序,该应用程序在mapview上追踪用户路径。当用户左转地图时,我想要达到的目标应该以这样的方式旋转它,使得mapview的头部始终指向上方。我希望这是有道理的。Android旋转MapView

我碰到罗曼盖伊先生的帖子的,他说

我在过去做到了这一点,它 需要创建一个自定义的ViewGroup 是旋转画布在 dispatchDraw()方法。您还需要 来增加MapView的大小(以便在旋转 时绘制足够的像素。)您还需要在 dispatchTouchEvent()中旋转 touch事件。或者,如果您使用 Android 3.0的,你可以简单地调用 theMapView.rotate():

有谁来到翻过一些解决方案类同我的问题?一个可行的例子将是非常好的:)

+0

见我的答案在这里:旋转MapView的Android中(http://stackoverflow.com/a/12126276/546054) – TouchBoarder 2012-10-14 20:27:26

回答

8

请记住,这不是一个理想的方法,因为地图上的文本是一个静态图像,并会随地图块一起旋转(在某些时候它会颠倒) 。

下面是如何将MapView放入您自己的Layout小部件并旋转它的示例。我已经使用OpenStreetMaps完成了它,但Google地图应该完全相同。

首先由它制造的“旋转” 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)); 
    } 
} 

环绕你的MapViewlayout.xml

<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> 

现在,每当你收到一个地理修复时间,更新旋转的轴承布局,它应该转向。

+0

嘿,感谢您的回答。我用你的代码做了一个旋转的布局,它可以工作,但视图不居中。我的意思是布局比屏幕大,但它只通过右侧和底侧退出屏幕。我将如何去围绕“旋转线性布局”进行对中? – bughi 2012-05-22 19:47:08

+0

@bughi我认为在dispatchDraw你必须有一些pCanvas.translate(x,y)来移动画布。然而,如何精确计算x和y我不能说。 – Ridcully 2012-08-20 18:18:34

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项目的一部分