如何添加覆蓋物,實現周邊搜索,以及對覆蓋物的點擊出現介紹等效果。
效果圖:
我們的需求是,當用戶點擊衣食住行,或者對對附近搜索是,從服務器返回數據(經緯度,商家信息,介紹等),然後動態生成覆蓋物,實現上述效果。關於圖片,由於手機上的內存的有限性,所有的圖片下載完成都應該存入預設的緩存中,例如LruCache,然後需要的時候從緩存取,緩存沒有,下載完成放入緩存;即實現所有的圖片所占的內存永遠不會超過緩存預設的內存值,當然了本篇的重點不是這個,我直接拿了幾張圖片加入我們的項目中模擬。
1、承載數據的實體
我們從服務器返回的數據部分,最終可能是個Json數組,我們需要轉換為實體集合,即下面的Info.java:
[java] view plaincopy
- package com.zhy.zhy_baidu_ditu_demo03;
-
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.List;
-
- public class Info implements Serializable
- {
- private static final long serialVersionUID = -758459502806858414L;
- /**
- * 精度
- */
- private double latitude;
- /**
- * 緯度
- */
- private double longitude;
- /**
- * 圖片ID,真實項目中可能是圖片路徑
- */
- private int imgId;
- /**
- * 商家名稱
- */
- private String name;
- /**
- * 距離
- */
- private String distance;
- /**
- * 贊數量
- */
- private int zan;
-
- public static List infos = new ArrayList();
-
- static
- {
- infos.add(new Info(34.242652, 108.971171, R.drawable.a01, 英倫貴族小旅館,
- 距離209米, 1456));
- infos.add(new Info(34.242952, 108.972171, R.drawable.a02, 沙井國際洗浴會所,
- 距離897米, 456));
- infos.add(new Info(34.242852, 108.973171, R.drawable.a03, 五環服裝城,
- 距離249米, 1456));
- infos.add(new Info(34.242152, 108.971971, R.drawable.a04, 老米家泡馍小炒,
- 距離679米, 1456));
- }
-
- public Info()
- {
- }
-
- public Info(double latitude, double longitude, int imgId, String name,
- String distance, int zan)
- {
- super();
- this.latitude = latitude;
- this.longitude = longitude;
- this.imgId = imgId;
- this.name = name;
- this.distance = distance;
- this.zan = zan;
- }
-
- public double getLatitude()
- {
- return latitude;
- }
-
- public void setLatitude(double latitude)
- {
- this.latitude = latitude;
- }
-
- public double getLongitude()
- {
- return longitude;
- }
-
- public void setLongitude(double longitude)
- {
- this.longitude = longitude;
- }
-
- public String getName()
- {
- return name;
- }
-
- public int getImgId()
- {
- return imgId;
- }
-
- public void setImgId(int imgId)
- {
- this.imgId = imgId;
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
-
- public String getDistance()
- {
- return distance;
- }
-
- public void setDistance(String distance)
- {
- this.distance = distance;
- }
-
- public int getZan()
- {
- return zan;
- }
-
- public void setZan(int zan)
- {
- this.zan = zan;
- }
-
- }
我直接在實體類中聲明了一個靜態列表集合,模擬從服務器返回的數據Info.infos。
2、地圖中動態添加Overlay
為了方便,我把按鈕都放在menu菜單中:
[java] view plaincopy
- @Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
- switch (item.getItemId())
- {
- case R.id.id_menu_map_addMaker:
- addInfosOverlay(Info.infos);
- break;
- ...
- }
- }
[java] view plaincopy
- /**
- * 初始化圖層
- */
- public void addInfosOverlay(List infos)
- {
- mBaiduMap.clear();
- LatLng latLng = null;
- OverlayOptions overlayOptions = null;
- Marker marker = null;
- for (Info info : infos)
- {
- // 位置
- latLng = new LatLng(info.getLatitude(), info.getLongitude());
- // 圖標
- overlayOptions = new MarkerOptions().position(latLng)
- .icon(mIconMaker).zIndex(5);
- marker = (Marker) (mBaiduMap.addOverlay(overlayOptions));
- Bundle bundle = new Bundle();
- bundle.putSerializable(info, info);
- marker.setExtraInfo(bundle);
- }
- // 將地圖移到到最後一個經緯度位置
- MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
- mBaiduMap.setMapStatus(u);
- }
可以看到,我們迭代添加了Overlay,然後在返回的Marker中設置了商家的信息,用戶用戶對Marker的點擊時,拿到商家數據生成詳細信息布局。
3、為地圖上的Marker添加點擊事件:
[java] view plaincopy
- //對Marker的點擊
- mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener()
- {
- @Override
- public boolean onMarkerClick(final Marker marker)
- {
- //獲得marker中的數據
- Info info = (Info) marker.getExtraInfo().get(info);
-
- InfoWindow mInfoWindow;
- //生成一個TextView用戶在地圖中顯示InfoWindow
- TextView location = new TextView(getApplicationContext());
- location.setBackgroundResource(R.drawable.location_tips);
- location.setPadding(30, 20, 30, 50);
- location.setText(info.getName());
- //將marker所在的經緯度的信息轉化成屏幕上的坐標
- final LatLng ll = marker.getPosition();
- Point p = mBaiduMap.getProjection().toScreenLocation(ll);
- Log.e(TAG, --! + p.x + , + p.y);
- p.y -= 47;
- LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
- //為彈出的InfoWindow添加點擊事件
- mInfoWindow = new InfoWindow(location, llInfo,
- new OnInfoWindowClickListener()
- {
-
- @Override
- public void onInfoWindowClick()
- {
- //隱藏InfoWindow
- mBaiduMap.hideInfoWindow();
- }
- });
- //顯示InfoWindow
- mBaiduMap.showInfoWindow(mInfoWindow);
- //設置詳細信息布局為可見
- mMarkerInfoLy.setVisibility(View.VISIBLE);
- //根據商家信息為詳細信息布局設置信息
- popupInfo(mMarkerInfoLy, info);
- return true;
- }
- });
根據商家的信息Info.java為詳細信息布局中的控件添加數據(記得生成TextView的時候,先設置背景,再設置padding,不然可能會失效~~~)
[java] view plaincopy
- /**
- * 根據info為布局上的控件設置信息
- *
- * @param mMarkerInfo2
- * @param info
- */
- protected void popupInfo(RelativeLayout mMarkerLy, Info info)
- {
- ViewHolder viewHolder = null;
- if (mMarkerLy.getTag() == null)
- {
- viewHolder = new ViewHolder();
- viewHolder.infoImg = (ImageView) mMarkerLy
- .findViewById(R.id.info_img);
- viewHolder.infoName = (TextView) mMarkerLy
- .findViewById(R.id.info_name);
- viewHolder.infoDistance = (TextView) mMarkerLy
- .findViewById(R.id.info_distance);
- viewHolder.infoZan = (TextView) mMarkerLy
- .findViewById(R.id.info_zan);
-
- mMarkerLy.setTag(viewHolder);
- }
- viewHolder = (ViewHolder) mMarkerLy.getTag();
- viewHolder.infoImg.setImageResource(info.getImgId());
- viewHolder.infoDistance.setText(info.getDistance());
- viewHolder.infoName.setText(info.getName());
- viewHolder.infoZan.setText(info.getZan() + );
- }
這裡我們使用了一個ViewHoler進行控件的復用,讓findViewById只會執行一次
[java] view plaincopy
- /**
- * 復用彈出面板mMarkerLy的控件
- *
- * @author zhy
- *
- */
- private class ViewHolder
- {
- ImageView infoImg;
- TextView infoName;
- TextView infoDistance;
- TextView infoZan;
- }
最後添加地圖的單擊事件,隱藏出現的詳細信息布局和InfoWindow
[java] view plaincopy
- mBaiduMap.setOnMapClickListener(new OnMapClickListener()
- {
-
- @Override
- public boolean onMapPoiClick(MapPoi arg0)
- {
- return false;
- }
-
- @Override
- public void onMapClick(LatLng arg0)
- {
- mMarkerInfoLy.setVisibility(View.GONE);
- mBaiduMap.hideInfoWindow();
-
- }
- });
最後看一下我們的布局文件:
[html] view plaincopy
- xmlns:tools=http://schemas.android.com/tools
- android:layout_width=match_parent
- android:layout_height=match_parent >
-
- android:id=@+id/id_bmapView
- android:layout_width=fill_parent
- android:layout_height=fill_parent
- android:clickable=true />
-
- android:id=@+id/id_marker_info
- android:visibility=gone
- android:layout_width=fill_parent
- android:layout_height=220dp
- android:layout_alignParentBottom=true
- android:background=#CC4e5a6b
- android:clickable=true >
-
- android:id=@+id/info_img
- android:layout_width=fill_parent
- android:layout_height=150dp
- android:layout_marginBottom=10dp
- android:layout_marginLeft=12dp
- android:layout_marginRight=12dp
- android:layout_marginTop=10dp
- android:alpha=1.0
- android:background=@drawable/map_image_border_white
- android:clickable=true
- android:scaleType=fitXY
- android:src=@drawable/a04 />
-
- android:layout_width=fill_parent
- android:layout_height=50dp
- android:layout_alignParentBottom=true
- android:background=@drawable/bg_map_bottom >
-
- android:layout_width=fill_parent
- android:layout_height=wrap_content
- android:layout_centerVertical=true
- android:layout_marginLeft=20dp
- android:orientation=vertical >
-
- android:id=@+id/info_name
- android:layout_width=wrap_content
- android:layout_height=wrap_content
- android:text=老米家泡馍小炒
- android:textColor=#FFF5EB />
-
- android:id=@+id/info_distance
- android:layout_width=wrap_content
- android:layout_height=wrap_content
- android:text=距離200米
- android:textColor=#FFF5EB />
-
-
- android:layout_width=wrap_content
- android:layout_height=wrap_content
- android:layout_alignParentRight=true
- android:layout_centerVertical=true
- android:layout_marginRight=20dp
- android:orientation=horizontal >
-
- android:layout_width=wrap_content
- android:layout_height=wrap_content
- android:onClick=zan
- android:src=@drawable/map_zan />
-
- android:id=@+id/info_zan
- android:layout_width=wrap_content
- android:layout_height=wrap_content
- android:layout_gravity=center
- android:text=652
- android:textColor=#FFF5EB />
-
-
-
-
除了MapView,其他都是詳細信息的布局,默認是隱藏的,當用戶點擊Marker顯示以及設置初值,當用戶單擊地圖時再將其隱藏。