android百度地圖 添加覆蓋物Marker與InfoWindow的使用

如何添加覆蓋物,實現周邊搜索,以及對覆蓋物的點擊出現介紹等效果。

效果圖:

我們的需求是,當用戶點擊衣食住行,或者對對附近搜索是,從服務器返回數據(經緯度,商傢信息,介紹等),然後動態生成覆蓋物,實現上述效果。關於圖片,由於手機上的內存的有限性,所有的圖片下載完成都應該存入預設的緩存中,例如LruCache,然後需要的時候從緩存取,緩存沒有,下載完成放入緩存;即實現所有的圖片所占的內存永遠不會超過緩存預設的內存值,當然瞭本篇的重點不是這個,我直接拿瞭幾張圖片加入我們的項目中模擬。

1、承載數據的實體

我們從服務器返回的數據部分,最終可能是個Json數組,我們需要轉換為實體集合,即下面的Info.java:

 

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. package com.zhy.zhy_baidu_ditu_demo03;
  2.  
  3. import java.io.Serializable;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6.  
  7. public class Info implements Serializable
  8. {
  9. private static final long serialVersionUID = -758459502806858414L;
  10. /**
  11. * 精度
  12. */
  13. private double latitude;
  14. /**
  15. * 緯度
  16. */
  17. private double longitude;
  18. /**
  19. * 圖片ID,真實項目中可能是圖片路徑
  20. */
  21. private int imgId;
  22. /**
  23. * 商傢名稱
  24. */
  25. private String name;
  26. /**
  27. * 距離
  28. */
  29. private String distance;
  30. /**
  31. * 贊數量
  32. */
  33. private int zan;
  34.  
  35. public static List infos = new ArrayList();
  36.  
  37. static
  38. {
  39. infos.add(new Info(34.242652, 108.971171, R.drawable.a01, 英倫貴族小旅館,
  40. 距離209米, 1456));
  41. infos.add(new Info(34.242952, 108.972171, R.drawable.a02, 沙井國際洗浴會所,
  42. 距離897米, 456));
  43. infos.add(new Info(34.242852, 108.973171, R.drawable.a03, 五環服裝城,
  44. 距離249米, 1456));
  45. infos.add(new Info(34.242152, 108.971971, R.drawable.a04, 老米傢泡饃小炒,
  46. 距離679米, 1456));
  47. }
  48.  
  49. public Info()
  50. {
  51. }
  52.  
  53. public Info(double latitude, double longitude, int imgId, String name,
  54. String distance, int zan)
  55. {
  56. super();
  57. this.latitude = latitude;
  58. this.longitude = longitude;
  59. this.imgId = imgId;
  60. this.name = name;
  61. this.distance = distance;
  62. this.zan = zan;
  63. }
  64.  
  65. public double getLatitude()
  66. {
  67. return latitude;
  68. }
  69.  
  70. public void setLatitude(double latitude)
  71. {
  72. this.latitude = latitude;
  73. }
  74.  
  75. public double getLongitude()
  76. {
  77. return longitude;
  78. }
  79.  
  80. public void setLongitude(double longitude)
  81. {
  82. this.longitude = longitude;
  83. }
  84.  
  85. public String getName()
  86. {
  87. return name;
  88. }
  89.  
  90. public int getImgId()
  91. {
  92. return imgId;
  93. }
  94.  
  95. public void setImgId(int imgId)
  96. {
  97. this.imgId = imgId;
  98. }
  99.  
  100. public void setName(String name)
  101. {
  102. this.name = name;
  103. }
  104.  
  105. public String getDistance()
  106. {
  107. return distance;
  108. }
  109.  
  110. public void setDistance(String distance)
  111. {
  112. this.distance = distance;
  113. }
  114.  
  115. public int getZan()
  116. {
  117. return zan;
  118. }
  119.  
  120. public void setZan(int zan)
  121. {
  122. this.zan = zan;
  123. }
  124.  
  125. }
    我直接在實體類中聲明瞭一個靜態列表集合,模擬從服務器返回的數據Info.infos。

     

    2、地圖中動態添加Overlay

    為瞭方便,我把按鈕都放在menu菜單中:

     

    [java] view plaincopy在CODE上查看代碼片派生到我的代碼片

    1. @Override
    2. public boolean onOptionsItemSelected(MenuItem item)
    3. {
    4. switch (item.getItemId())
    5. {
    6. case R.id.id_menu_map_addMaker:
    7. addInfosOverlay(Info.infos);
    8. break;

    9. [java] view plaincopy在CODE上查看代碼片派生到我的代碼片

      1. /**
      2. * 初始化圖層
      3. */
      4. public void addInfosOverlay(List infos)
      5. {
      6. mBaiduMap.clear();
      7. LatLng latLng = null;
      8. OverlayOptions overlayOptions = null;
      9. Marker marker = null;
      10. for (Info info : infos)
      11. {
      12. // 位置
      13. latLng = new LatLng(info.getLatitude(), info.getLongitude());
      14. // 圖標
      15. overlayOptions = new MarkerOptions().position(latLng)
      16. .icon(mIconMaker).zIndex(5);
      17. marker = (Marker) (mBaiduMap.addOverlay(overlayOptions));
      18. Bundle bundle = new Bundle();
      19. bundle.putSerializable(info, info);
      20. marker.setExtraInfo(bundle);
      21. }
      22. // 將地圖移到到最後一個經緯度位置
      23. MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
      24. mBaiduMap.setMapStatus(u);
      25. }
        可以看到,我們迭代添加瞭Overlay,然後在返回的Marker中設置瞭商傢的信息,用戶用戶對Marker的點擊時,拿到商傢數據生成詳細信息佈局。

         

        3、為地圖上的Marker添加點擊事件:

         

        [java] view plaincopy在CODE上查看代碼片派生到我的代碼片

        1. //對Marker的點擊
        2. mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener()
        3. {
        4. @Override
        5. public boolean onMarkerClick(final Marker marker)
        6. {
        7. //獲得marker中的數據
        8. Info info = (Info) marker.getExtraInfo().get(info);
        9.  
        10. InfoWindow mInfoWindow;
        11. //生成一個TextView用戶在地圖中顯示InfoWindow
        12. TextView location = new TextView(getApplicationContext());
        13. location.setBackgroundResource(R.drawable.location_tips);
        14. location.setPadding(30, 20, 30, 50);
        15. location.setText(info.getName());
        16. //將marker所在的經緯度的信息轉化成屏幕上的坐標
        17. final LatLng ll = marker.getPosition();
        18. Point p = mBaiduMap.getProjection().toScreenLocation(ll);
        19. Log.e(TAG, –! + p.x + , + p.y);
        20. p.y -= 47;
        21. LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
        22. //為彈出的InfoWindow添加點擊事件
        23. mInfoWindow = new InfoWindow(location, llInfo,
        24. new OnInfoWindowClickListener()
        25. {
        26.  
        27. @Override
        28. public void onInfoWindowClick()
        29. {
        30. //隱藏InfoWindow
        31. mBaiduMap.hideInfoWindow();
        32. }
        33. });
        34. //顯示InfoWindow
        35. mBaiduMap.showInfoWindow(mInfoWindow);
        36. //設置詳細信息佈局為可見
        37. mMarkerInfoLy.setVisibility(View.VISIBLE);
        38. //根據商傢信息為詳細信息佈局設置信息
        39. popupInfo(mMarkerInfoLy, info);
        40. return true;
        41. }
        42. });
          根據商傢的信息Info.java為詳細信息佈局中的控件添加數據(記得生成TextView的時候,先設置背景,再設置padding,不然可能會失效~~~)

           

           

          [java] view plaincopy在CODE上查看代碼片派生到我的代碼片

          1. /**
          2. * 根據info為佈局上的控件設置信息
          3. *
          4. * @param mMarkerInfo2
          5. * @param info
          6. */
          7. protected void popupInfo(RelativeLayout mMarkerLy, Info info)
          8. {
          9. ViewHolder viewHolder = null;
          10. if (mMarkerLy.getTag() == null)
          11. {
          12. viewHolder = new ViewHolder();
          13. viewHolder.infoImg = (ImageView) mMarkerLy
          14. .findViewById(R.id.info_img);
          15. viewHolder.infoName = (TextView) mMarkerLy
          16. .findViewById(R.id.info_name);
          17. viewHolder.infoDistance = (TextView) mMarkerLy
          18. .findViewById(R.id.info_distance);
          19. viewHolder.infoZan = (TextView) mMarkerLy
          20. .findViewById(R.id.info_zan);
          21.  
          22. mMarkerLy.setTag(viewHolder);
          23. }
          24. viewHolder = (ViewHolder) mMarkerLy.getTag();
          25. viewHolder.infoImg.setImageResource(info.getImgId());
          26. viewHolder.infoDistance.setText(info.getDistance());
          27. viewHolder.infoName.setText(info.getName());
          28. viewHolder.infoZan.setText(info.getZan() + );
          29. }
            這裡我們使用瞭一個ViewHoler進行控件的復用,讓findViewById隻會執行一次

             

             

            [java] view plaincopy在CODE上查看代碼片派生到我的代碼片

            1. /**
            2. * 復用彈出面板mMarkerLy的控件
            3. *
            4. * @author zhy
            5. *
            6. */
            7. private class ViewHolder
            8. {
            9. ImageView infoImg;
            10. TextView infoName;
            11. TextView infoDistance;
            12. TextView infoZan;
            13. }
              最後添加地圖的單擊事件,隱藏出現的詳細信息佈局和InfoWindow

               

               

              [java] view plaincopy在CODE上查看代碼片派生到我的代碼片

              1. mBaiduMap.setOnMapClickListener(new OnMapClickListener()
              2. {
              3.  
              4. @Override
              5. public boolean onMapPoiClick(MapPoi arg0)
              6. {
              7. return false;
              8. }
              9.  
              10. @Override
              11. public void onMapClick(LatLng arg0)
              12. {
              13. mMarkerInfoLy.setVisibility(View.GONE);
              14. mBaiduMap.hideInfoWindow();
              15.  
              16. }
              17. });
                最後看一下我們的佈局文件:

                 

                 

                [html] view plaincopy在CODE上查看代碼片派生到我的代碼片

                1. xmlns:tools=https://schemas.android.com/tools
                2. android:layout_width=match_parent
                3. android:layout_height=match_parent >
                4.  
                5. android:id=@+id/id_bmapView
                6. android:layout_width=fill_parent
                7. android:layout_height=fill_parent
                8. android:clickable=true />
                9.  
                10. android:id=@+id/id_marker_info
                11. android:visibility=gone
                12. android:layout_width=fill_parent
                13. android:layout_height=220dp
                14. android:layout_alignParentBottom=true
                15. android:background=#CC4e5a6b
                16. android:clickable=true >
                17.  
                18. android:id=@+id/info_img
                19. android:layout_width=fill_parent
                20. android:layout_height=150dp
                21. android:layout_marginBottom=10dp
                22. android:layout_marginLeft=12dp
                23. android:layout_marginRight=12dp
                24. android:layout_marginTop=10dp
                25. android:alpha=1.0
                26. android:background=@drawable/map_image_border_white
                27. android:clickable=true
                28. android:scaleType=fitXY
                29. android:src=@drawable/a04 />
                30.  
                31. android:layout_width=fill_parent
                32. android:layout_height=50dp
                33. android:layout_alignParentBottom=true
                34. android:background=@drawable/bg_map_bottom >
                35.  
                36. android:layout_width=fill_parent
                37. android:layout_height=wrap_content
                38. android:layout_centerVertical=true
                39. android:layout_marginLeft=20dp
                40. android:orientation=vertical >
                41.  
                42. android:id=@+id/info_name
                43. android:layout_width=wrap_content
                44. android:layout_height=wrap_content
                45. android:text=老米傢泡饃小炒
                46. android:textColor=#FFF5EB />
                47.  
                48. android:id=@+id/info_distance
                49. android:layout_width=wrap_content
                50. android:layout_height=wrap_content
                51. android:text=距離200米
                52. android:textColor=#FFF5EB />
                53.  
                54.  
                55. android:layout_width=wrap_content
                56. android:layout_height=wrap_content
                57. android:layout_alignParentRight=true
                58. android:layout_centerVertical=true
                59. android:layout_marginRight=20dp
                60. android:orientation=horizontal >
                61.  
                62. android:layout_width=wrap_content
                63. android:layout_height=wrap_content
                64. android:onClick=zan
                65. android:src=@drawable/map_zan />
                66.  
                67. android:id=@+id/info_zan
                68. android:layout_width=wrap_content
                69. android:layout_height=wrap_content
                70. android:layout_gravity=center
                71. android:text=652
                72. android:textColor=#FFF5EB />
                73.  
                74.  
                75.  
                76.  
                77. 除瞭MapView,其他都是詳細信息的佈局,默認是隱藏的,當用戶點擊Marker顯示以及設置初值,當用戶單擊地圖時再將其隱藏。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。