在android 的google map中实现compass mode的2种实现:
1.在map over lay上添加指南针:
private MyLocationOverlay mlo;
// create myLocationOverlay
mlo = new MyLocationOverlay(this, map);
mlo.enableMyLocation();
map.getOverlays().add(mlo);
if (mToggleMapCompass.isChecked()) {//compass mode 切换
// enable or disable map compass mode
2.实现整个地图的指南针方式旋转:
首先,写一个容器类MapLayout 来放置map,通过设置容器类MapLayout 的角度angle 来旋转map:
package com.mc.yellowbook.android.map;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class MapLayout extends ViewGroup {
public MapLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.angle = 0;
}
public MapLayout(Context context) {
super(context);
this.angle = 0;
}
private static float SQ2 = 1.414213562373095f;
private float angle;
@Override
protected void dispatchDraw(Canvas canvas) {
// canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
canvas.rotate(-angle, getWidth() * 0.5f, getHeight() * 0.5f);
super.dispatchDraw(canvas);
} catch (Exception e) {
}
// canvas.restore();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
final int width = getWidth();
final int height = getHeight();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View view = getChildAt(i);
final int childWidth = view.getMeasuredWidth();
final int childHeight = view.getMeasuredHeight();
final int childLeft = (width - childWidth) / 2;
final int childTop = (height - childHeight) / 2;
view.layout(childLeft, childTop, childLeft + childWidth, childTop
+ childHeight);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int w = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int h = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int sizeSpec;
if (w > h) {
sizeSpec = MeasureSpec.makeMeasureSpec((int) (w * SQ2),
MeasureSpec.EXACTLY);
} else {
sizeSpec = MeasureSpec.makeMeasureSpec((int) (h * SQ2),
MeasureSpec.EXACTLY);
}
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(sizeSpec, sizeSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void setAngle(float angleSet) {
this.angle = angleSet;
invalidate();
}
public float getAngle() {
return angle;
}
}
然后再mapActivity中设置orientation sensor来监测角度的变化,从而重绘地图:
public static int ORIENT_PORTRAIT = 1;
public static int ORIENT_LANDSCAPE = 2;
public static final int MAP_DRAG_MODE = 3;
public static final int MAP_ROTATE_MODE = 4;
public static int SENSOR_DELICACY = 7;
private Sensor sensor = null;
private SensorManager sm = null;
private float oriX;
// get reference to SensorManager
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> sensors = sm.getSensorList(Sensor.TYPE_ORIENTATION);
if (sensors == null || sensors.size() < 1) {
showToast(this, R.string.mobile_find_cache_no_sensor);
}
// get reference to Sensor
sensor = sensors.get(0);
@Override
public void onSensorChanged(SensorEvent event) {
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
float aglX;
if (getOrientation() == MobileFindCacheResultActivity.ORIENT_LANDSCAPE) {
aglX = (event.values[0] + 90) % 360;
} else {
aglX = event.values[0];
}
// System.out.println(Arrays.asList(event.values[]));
// get the value if face direction changed
if (Math.abs(oriX - aglX) >= SENSOR_DELICACY) {
oriX = aglX;
}
if (mapOverlay != null && mMapLayout != null) {
if (mapOverlay.getMode() == MobileFindCacheResultActivity.MAP_ROTATE_MODE) {
mMapLayout.setAngle(oriX);
} else {
mMapLayout.setAngle(0);
}
}
}
}
}
//获取手机屏幕 的纵横
public int getOrientation(){
return getResources().getConfiguration().orientation;
}
// 在onresume中注册sensor监听器
@Override
protected void onResume() {
sm.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
//compass mode切换
// enable or disable map compass mode
if (mToggleMapCompass.isChecked()) {
mapOverlay.setMode(MAP_ROTATE_MODE);
} else {
mapOverlay.setMode(MAP_DRAG_MODE);
}
其中mapOverlay是map的overlay类。