我正在创建一个在mapview上追踪用户路径的应用程序。当用户左转为实例地图时我想要实现的应该是自我旋转,使得mapview的头部始终指向向上的方向。我希望这是有道理的。
我遇到了Romain Guy先生的帖子,他说
我过去做过这件事 需要创建自定义ViewGroup 在那里旋转画布 dispatchDraw()方法。你还需要 增加MapView的大小 (这样它可以吸引足够的像素 旋转。)你还需要旋转 中的触摸事件 dispatchTouchEvent()。或者如果你使用 你可以简单地调用Android 3.0 theMapView.rotate():
是否有人遇到过与我的问题类似的解决方案?一个工作的例子非常好:)
答案 0 :(得分:8)
请注意,这不是一种理想的方法,因为地图上的文字是静态图片,会随地图图块一起旋转(在某些时候它会颠倒)。
以下是如何将MapView
放入您自己的Layout
窗口小部件并旋转它的示例。我已经使用OpenStreetMaps完成了它,但对于谷歌地图应该完全相同。
首先创建"旋转" 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));
}
}
在MapView
layout.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>
现在,每次收到地理位置修复时,都要更新旋转布局的方位,然后转动。
答案 1 :(得分: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);
}
答案 2 :(得分: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项目的一部分