在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);

//compass mode 切换

// enable or disable map compass mode

if (mToggleMapCompass.isChecked()) {
mlo.enableCompass();
} else {
mlo.disableCompass();
}

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






更多相关文章

  1. android 带你从源码的角度解析Scroller的滚动实现原理
  2. [Android]用架构师角度看插件化--章节列表
  3. Android方向传感器实践——自己动手做指南针
  4. Android 虚拟摇杆,多种模式回调,返回距离级别,方向,角度。
  5. Android学习笔记4之容器
  6. android 页面容器 下一页很上一页view
  7. [android]布局(容器)简介和使用方法

随机推荐

  1. Android(安卓)IPC 通讯机制源码分析
  2. Android周学习Step By Step(6)--Android的
  3. Android(安卓)Handler详解
  4. Android(安卓)如何在Eclipse中查看Androi
  5. Android简明开发教程二十四:总结及示例代
  6. Android(安卓)Layout XML属性
  7. Android(安卓)下使用 JSON 实现 HTTP 请
  8. Android(安卓)Market api
  9. 在android虚拟机中安装删除应用程序
  10. android同一个程序中使用多个地图出现混