前段时间研究了一下百度地图,看见一些其他的应用在使用百度地图时,地图上的标注物好像都是自己定义的并且带有立体感,所以就自己研究了一些怎样自定义
布局进行地图的标注,比如在地图上标注你的好友,并且将好友的名字在标注物上显示出来,这样就需要进行自定义的标注物,google了很多博客,但是都不是我
想要的效果,他们的自定义都没有自定义自己的布局。下面将自己的做的记录一下。
首先我们知道百度地图的标注物使用的是item.setMarker(draw),这个item是OverlayItem对象,draw是一个Drawable对象。也就是说在百度地图上进行的标注物
必须是Drawable类型的,所以我们就应该去想怎样将一个布局对象转化为Drawable对象,同时布局对象通常都是一个View对象。所以接下来我们就应该思考怎样
将一个View对象转化为一个Drawable对象。这个google一下很容易就找到方法:
可以将View转化成BitMap对象,然后将BItmap对象转化成BitMapDrawable对象就Ok了(因为BitMapDrawable是Drawable的子类)
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
BitmapDrawable draw = new BitmapDrawable(bitmap);
这样就能够将draw在百度地图上进行标注了。
接下来上一个百度地图的小例子:将地图的标注和定位进行了分开,并且定时进行标注,能够手动的进行定位。记得要在AndroidManiFest中添加相关的权限。
public class MapApplication extends Application{ BMapManager bMapManager; public static final String pwd="XX"; private static MapApplication instance; public boolean m_bKeyRight = true; @Override public void onCreate() { super.onCreate(); instance = this; initMap(); } @Override public void onTerminate() { super.onTerminate(); } public void initMap(){ if(bMapManager==null){ bMapManager = new BMapManager(getApplicationContext()); } if(!bMapManager.init(pwd,new MyGeneralListener())){ Toast.makeText(getApplicationContext(), "初始化错误", Toast.LENGTH_SHORT).show(); } } /** 常用事件监听,用来处理通常的网络错误,授权验证错误等 */ public static class MyGeneralListener implements MKGeneralListener { @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { Toast.makeText(MapApplication.instance, "您的网络出错啦!", Toast.LENGTH_LONG).show(); } else if (iError == MKEvent.ERROR_NETWORK_DATA) { Toast.makeText(MapApplication.instance, "输入正确的检索条件!", Toast.LENGTH_LONG).show(); } } @Override public void onGetPermissionState(int iError) { if (iError == MKEvent.ERROR_PERMISSION_DENIED) { //授权Key错误: Toast.makeText(MapApplication.instance, "百度地图Key失效!", Toast.LENGTH_LONG).show(); MapApplication.instance.m_bKeyRight = false; } } } }
public class LayoutLabel implements Runnable{ ItemizedOverlay<OverlayItem> overlay; Drawable marker; Context context; MapView mapView; private double latitude = 23.165281,longitude = 113.425987; View view; public static volatile boolean isStop = false; public LayoutLabel(Context context,MapView mapView){ this.context = context; this.mapView = mapView; init(); } public void init(){ marker = context.getResources().getDrawable(R.drawable.main_map_icon_nav_check); marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker .getIntrinsicHeight()); overlay = new ItemizedOverlay<OverlayItem>(marker, mapView); mapView.getOverlays().add(overlay); view= (RelativeLayout)LayoutInflater.from(context).inflate(R.layout.picc_worker_location, null); TextView tv = (TextView)view.findViewById(R.id.picc_worker_name); tv.setText("曹操"); mapView.addView(view);//将子view添加到父容器中,所有的标注物都是mapView上进行标注的。 view.setVisibility(View.GONE); } public void label(){ overlay.removeAll(); mapView.refresh(); GeoPoint point = new GeoPoint((int)(latitude*1e6), (int)(longitude* 1e6)); OverlayItem item = new OverlayItem(point, "MapApplication", null); BitmapDrawable draw = getDrawableFromBitmap(getBitmapFromView(view)); draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw .getIntrinsicHeight()); item.setMarker(draw); overlay.addItem(item); mapView.refresh(); } public Bitmap getBitmapFromView(View view) { //如果没有将view指定 parent view 那么下面这句则会出现空指针异常 view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bitmap = view.getDrawingCache(); return bitmap; } public BitmapDrawable getDrawableFromBitmap(Bitmap bitmap){ BitmapDrawable draw = new BitmapDrawable(Resources.getSystem(), bitmap); draw.setBounds(0, 0, draw.getIntrinsicWidth(), draw .getIntrinsicHeight()); return draw; } @Override public void run() { while(!isStop){ label(); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } }上面的代码是定时进行自定义的地图标注物定位,先将要标注的View添加到mapView上。然后进行上述的转化使用setMarker方法进行定位标注。
public class LayoutView { MapView mapView; MapController controller; Drawable marker; Context context; ItemizedOverlay<OverlayItem> overlay; public LayoutView(MapView mapView,Context context){ this.mapView = mapView; this.context = context; init(); } public void init(){ controller = mapView.getController(); GeoPoint point = new GeoPoint((int)(23.165281*1e6), (int)(113.425987* 1e6)); controller.setZoom(14); controller.enableClick(true); controller.setCenter(point); controller.animateTo(point); marker = context.getResources().getDrawable(R.drawable.main_map_icon_nav_check); overlay =new ItemizedOverlay<OverlayItem>(marker, mapView); mapView.getOverlays().add(overlay); mapView.setBuiltInZoomControls(true); mapView.refresh(); } public void mapOnClick(GeoPoint pointBaidu){ if(pointBaidu!=null){ overlay.removeAll(); OverlayItem item = new OverlayItem(pointBaidu, null, null); item.setMarker(marker); overlay.addItem(item); mapView.refresh(); controller.animateTo(pointBaidu); } } }
public class LocationMap{ LocationClient mLocClient; MapApplication application; Context context; public static double latitude=23.165281,longitude=113.425987; public static GeoPoint point; public static BDLocation location; public LocationMap(Context context){ this.context = context; application = (MapApplication)context.getApplicationContext(); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);//打开gps option.setCoorType("bd09ll");//设置坐标类型 option.setScanSpan(10000);//设置定时获取的时间间隔 option.disableCache(true);//设置是否要定位缓存 option.setPriority(LocationClientOption.GpsFirst);//设置定位优先方式 option.setProdName("MapActivity");//设置应用名字 mLocClient = new LocationClient(context); mLocClient.setLocOption(option); mLocClient.registerLocationListener(new MyLocationListenner()); mLocClient.start(); mLocClient.requestLocation(); } private class MyLocationListenner implements BDLocationListener{ @Override public void onReceiveLocation(BDLocation location) { if(location!=null){ latitude = location.getLatitude(); longitude = location.getLongitude(); LocationMap.location = location; point = new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()* 1e6)); } } @Override public void onReceivePoi(BDLocation location) { } } public static double getLatitude() { return latitude; } public static void setLatitude(double latitude) { LocationMap.latitude = latitude; } public static double getLongitude() { return longitude; } public static void setLongitude(double longitude) { LocationMap.longitude = longitude; } }这个类是使用定位SDK进行GPS的获取。
public class MapActivity extends Activity implements OnClickListener{ MapView mapView; Button btn; LayoutView layoutView; Thread thread; MapApplication application; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); application = (MapApplication)getApplication(); if (application.bMapManager == null) { application.bMapManager = new BMapManager(this); application.bMapManager.init(MapApplication.pwd, new MapApplication.MyGeneralListener()); } setContentView(R.layout.activity_map); mapView = (MapView)findViewById(R.id.mapView); btn = (Button)findViewById(R.id.request); btn.setOnClickListener(this); } @Override protected void onStart() { new LocationMap(this); layoutView = new LayoutView(mapView, this); thread = new Thread(new LayoutLabel(this, mapView)); thread.start(); super.onStart(); } @Override public void onClick(View v){ GeoPoint point = new GeoPoint((int)(LocationMap.latitude*1e6), (int)(LocationMap.longitude* 1e6)); layoutView.mapOnClick(point); } @Override protected void onDestroy() { stopLayoutLabel(); super.onDestroy(); } public void stopLayoutLabel(){ LayoutLabel.isStop = true; thread.interrupt(); mapView.destroy(); if (application.bMapManager != null){ application.bMapManager.destroy(); application.bMapManager = null; } } }
下面看下例子的效果。
现在只实现了自定义的标注和手动定位,但是怎样对标注物进行立体化,也就是添加阴影还没有找到方法,谁知道留言告知一下,一起进步学习。
这个小例子的下载链接http://download.csdn.net/detail/zkw12358/6688299 注意百度的验证码我去掉了,要运行的话自己去百度地图官网申请一个吧。