百度地图API之Marker的使用(Android)
最近在做一个APP,其中一个功能要在地图上显示酒店位置以及显示酒店的最低价格,要用到百度地图中的Overlay。
overlay有以下几种:
1)Overlay:它是所有覆盖物的抽象基类,所有的覆盖物均继承此类的方法,实现用户自定义图层显示;
2)MyLocationOverlay:一个负责显示用户当前位置的Overlay;
3)ItemizedOverlay:它包含了一个OverlayItem列表,相当于一组分条的Overlay,通过继承此类,将一组兴趣点显示在地图上;
4)PoiOverlay:本地搜索图层,提供某一特定地区的位置搜索服务,比如在北京市搜索“公园”,通过此图层将公园显示在地图上;
5)RouteOverlay:步行、驾车导航线路图层,将步行、驾车出行方案的路线及关键点显示在地图上;
6)TransitOverlay:公交换乘线路图层,将某一特定地区的公交出行方案的路线及换乘位置显示在地图上。
在3.0以后版本中百度地图api中overlay改变比较大,我刚才所说的功能在3.0以前的版本是可以通过自定义的Overlay继承ItemizedOverlay来实现,在3.0以后的版本中已经找不到ItemizedOverlay了,已经用Marker代替。官方的android demo也没有关于marker
的事例,网上资料也较少,网页版较为简单,android只能自己摸索了。
我们先来看看最终做出的效果,如下图所示:
下面是具体实现:
1.页面activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
2.自定义Marker
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:orientation="vertical" > 6 <LinearLayout 7 android:layout_width="wrap_content" 8 android:layout_height="wrap_content" 9 android:background="#fea531" 10 android:gravity="center" 11 android:orientation="horizontal" > 12 <ImageView 13 android:id="@+id/img_hotel_image" 14 android:layout_width="25dp" 15 android:layout_height="25dp" 16 android:padding="2dip" 17 android:scaleType="fitXY" 18 android:src="@drawable/hotel_pic" /> 19 <TextView 20 android:id="@+id/tv_hotel_price" 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:padding="5dip" 24 android:textColor="#ffffff" 25 android:textSize="14dp" /> 26 </LinearLayout> 27 <LinearLayout 28 android:layout_width="match_parent" 29 android:layout_height="wrap_content" 30 android:gravity="center" 31 android:orientation="horizontal" > 32 <ImageView 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:src="@drawable/custom_marker_triangle" /> 36 </LinearLayout> 37 </LinearLayout>
3.下面这段代码是关键,我们需要把自定义的view转换成Bitmap,MarkerOptions中的icon参数是Bitmap,自定义marker是很常用的,不明白百度为啥不搞个明显点方法,废了很多时间。
1 private Bitmap getViewBitmap(View addViewContent) { 2 3 addViewContent.setDrawingCacheEnabled(true); 4 5 addViewContent.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 6 addViewContent.layout(0, 0, addViewContent.getMeasuredWidth(), addViewContent.getMeasuredHeight()); 7 8 addViewContent.buildDrawingCache(); 9 Bitmap cacheBitmap = addViewContent.getDrawingCache(); 10 Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); 11 12 return bitmap; 13 }
4. 下面是Activity代码,
1 public class MainActivity extends Activity { 2 3 private List<Hotel> mData; 4 private SDKReceiver mReceiver; 5 6 private MapView mMapView; 7 private BaiduMap mBaiduMap; 8 9 LocationClient mLocClient; 10 private LocationMode mCurrentMode; 11 public MyLocationListenner myListener = new MyLocationListenner(); 12 BitmapDescriptor mCurrentMarker; 13 14 @Override 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 18 SDKInitializer.initialize(getApplicationContext()); 19 setContentView(R.layout.activity_main); 20 21 IntentFilter iFilter = new IntentFilter(); 22 iFilter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR); 23 iFilter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR); 24 mReceiver = new SDKReceiver(); 25 registerReceiver(mReceiver, iFilter); 26 27 // 地图初始化 28 mMapView = (MapView) findViewById(R.id.bmapView); 29 mBaiduMap = mMapView.getMap(); 30 //initLocation(); 31 mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() { 32 public boolean onMarkerClick(final Marker marker) { 33 // TO DO 34 35 return true; 36 } 37 }); 38 mData = getData(); 39 generateMarker(); 40 41 } 42 43 /** 44 * Inits the location. 45 */ 46 private void initLocation() { 47 48 // 开启定位图层 49 mBaiduMap.setMyLocationEnabled(true); 50 // 定位初始化 51 mLocClient = new LocationClient(this); 52 mLocClient.registerLocationListener(myListener); 53 LocationClientOption option = new LocationClientOption(); 54 option.setOpenGps(true);// 打开gps 55 option.setCoorType("bd09ll"); // 设置坐标类型 56 option.setScanSpan(1000); 57 mLocClient.setLocOption(option); 58 mLocClient.start(); 59 } 60 61 /** 62 * 定位SDK监听函数 63 */ 64 public class MyLocationListenner implements BDLocationListener { 65 @Override 66 public void onReceiveLocation(BDLocation location) { 67 // map view 销毁后不在处理新接收的位置 68 if (location == null || mMapView == null) 69 return; 70 MyLocationData locData = new MyLocationData.Builder().accuracy(location.getRadius()) 71 // 此处设置开发者获取到的方向信息,顺时针0-360 72 .direction(100).latitude(location.getLatitude()).longitude(location.getLongitude()).build(); 73 mBaiduMap.setMyLocationData(locData); 74 75 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); 76 MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll); 77 mBaiduMap.animateMapStatus(u); 78 79 } 80 81 public void onReceivePoi(BDLocation poiLocation) { 82 } 83 } 84 85 /** 86 * The Class SDKReceiver. 87 */ 88 public class SDKReceiver extends BroadcastReceiver { 89 public void onReceive(Context context, Intent intent) { 90 String s = intent.getAction(); 91 if (s.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) { 92 Toast toast = Toast.makeText(context, "key 验证出错! 请在 AndroidManifest.xml 文件中检查 key 设置", Toast.LENGTH_SHORT); 93 toast.setGravity(Gravity.CENTER, 0, 0); 94 toast.show(); 95 } else if (s.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) { 96 Toast toast = Toast.makeText(context, "网络出错", Toast.LENGTH_SHORT); 97 toast.setGravity(Gravity.CENTER, 0, 0); 98 toast.show(); 99 } 100 } 101 } 102 103 /** 104 * Gets the view bitmap. 105 * 106 * @param addViewContent 107 * the add view content 108 * @return the view bitmap 109 */ 110 private Bitmap getViewBitmap(View addViewContent) { 111 112 addViewContent.setDrawingCacheEnabled(true); 113 114 addViewContent.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 115 addViewContent.layout(0, 0, addViewContent.getMeasuredWidth(), addViewContent.getMeasuredHeight()); 116 117 addViewContent.buildDrawingCache(); 118 Bitmap cacheBitmap = addViewContent.getDrawingCache(); 119 Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); 120 121 return bitmap; 122 } 123 124 /** 125 * Gets the data. 126 * 127 * @return the data 128 */ 129 public List<Hotel> getData() { 130 try { 131 List<Hotel> resultList = new ArrayList<Hotel>(); 132 AssetManager manager = getApplicationContext().getAssets(); 133 InputStream file = manager.open("data.json"); 134 byte[] data = new byte[file.available()]; 135 file.read(data); 136 file.close(); 137 String jsonStr = new String(data); 138 JSONObject json = JSON.parseObject(jsonStr); 139 String jsonText = json.getString("Output"); 140 141 return JSONArray.parseArray(jsonText.toString(), Hotel.class); 142 143 } catch (IOException e) { 144 // TODO Auto-generated catch block 145 e.printStackTrace(); 146 return null; 147 } 148 } 149 150 public void generateMarker() { 151 152 for (Iterator iterator = mData.iterator(); iterator.hasNext();) { 153 Hotel hotel = (Hotel) iterator.next(); 154 LatLng ll = new LatLng(hotel.HotelLatitude, hotel.HotelLongitude); 155 View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.custom_marker, null); 156 157 // ImageView img_hotel_image= 158 // (ImageView)view.findViewById(R.id.img_hotel_image); 159 // new 160 // DownloadImageTask(img_hotel_image).execute(hotel.getHotelImageUrl()); 161 162 TextView tv_hotel_price = (TextView) view.findViewById(R.id.tv_hotel_price); 163 tv_hotel_price.setText(new StringBuilder().append(hotel.getHotelPrice()).append("¥起")); 164 BitmapDescriptor markerIcon = BitmapDescriptorFactory.fromBitmap(getViewBitmap(view)); 165 166 Bundle bundle = new Bundle(); 167 bundle.putSerializable("HOTEL", hotel); 168 169 OverlayOptions oo = new MarkerOptions().position(ll).icon(markerIcon).zIndex(9).draggable(true).extraInfo(bundle); 170 mBaiduMap.addOverlay(oo); 171 } 172 173 } 174 175 @Override 176 protected void onPause() { 177 mMapView.onPause(); 178 super.onPause(); 179 } 180 181 @Override 182 protected void onResume() { 183 mMapView.onResume(); 184 super.onResume(); 185 } 186 187 @Override 188 protected void onDestroy() { 189 // 退出时销毁定位 190 mLocClient.stop(); 191 // 关闭定位图层 192 mBaiduMap.setMyLocationEnabled(false); 193 mMapView.onDestroy(); 194 mMapView = null; 195 super.onDestroy(); 196 } 197 198 }
activity代码注释不多,有不明白的地方请自行下载官方Demo来研究。
代码下载地址 http://download.csdn.net/detail/showraining/9058193