前段时间研究了一下百度地图,看见一些其他的应用在使用百度地图时,地图上的标注物好像都是自己定义的并且带有立体感,所以就自己研究了一些怎样自定义
布局进行地图的标注,比如在地图上标注你的好友,并且将好友的名字在标注物上显示出来,这样就需要进行自定义的标注物,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;
}
}
}
}
首先在Application中进行百度地图的初始化。
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);
}
}
}
这个类是将定位和GPS获取进行了分离,进行手动定位时只要初始化这个类,调用其中的方法就能够进行手动定位。
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;
}
}
}
主Activity进行地图的控件的初始化。
下面看下例子的效果。
现在只实现了自定义的标注和手动定位,但是怎样对标注物进行立体化,也就是添加阴影还没有找到方法,谁知道留言告知一下,一起进步学习。
这个小例子的下载链接http://download.csdn.net/detail/zkw12358/6688299 注意百度的验证码我去掉了,要运行的话自己去百度地图官网申请一个吧。