2011-05-17 126 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項目的一部分