2015-06-20 53 views
7

我打算在utils庫中使用google地圖標記集羣,但google示例應用只顯示沒有任何infoWindow的標記集羣。我現在想知道,我無法顯示InfoWindow嗎?我希望InfoWindow能夠像標準谷歌地圖標記一樣顯示在標記上,而不是在羣集上顯示。Android Maps Utils集羣秀InfoWindow

代碼我有:(從谷歌例子)

public class BigClusteringDemoActivity extends FragmentActivity { 
    private ClusterManager<MyItem> mClusterManager; 
    private GoogleMap mMap; 

    private void readItems() { 
     InputStream inputStream = getResources().openRawResource(R.raw.radar_search); 
     List<MyItem> items = new MyItemReader().read(inputStream); 

     for (int i = 0; i < 10; i++) { 
      double offset = i/60d; 
      for (MyItem item : items) { 
       LatLng position = item.getPosition(); 
       double lat = position.latitude + offset; 
       double lng = position.longitude + offset; 
       MyItem offsetItem = new MyItem(lat, lng); 
       mClusterManager.addItem(offsetItem); 
      } 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.map); 

     mClusterManager = new ClusterManager<>(this, mMap); 

     mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 

     mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10)); 
     mMap.setOnCameraChangeListener(mClusterManager); 

     readItems(); 
    } 

} 
+0

看起來像這可能幫助:http://stackoverflow.com/questions/25968486/how-to-add-info-window-for-clustering-marker-in-android –

+0

@DanielNugent據我瞭解,鏈接你給我解釋瞭如何添加一個I nfoWindow到整個集羣。我想在單擊標記時顯示正常的InfoWindow,就像正常的谷歌地圖一樣 – qwertz

回答

23

這裏是基於this answer簡化且略微改性溶液。請注意,鏈接的答案爲標記和羣集實現InfoWindow。

該解決方案僅實現InfoWindows for Markers。

它與您如何爲不帶集羣的普通標記實現自定義InfoWindowAdapter類似,但需要額外要求您保留對當前選定項目的引用,以便您可以從它的MyItem實例中獲取標題和片段,因爲標記不像通常那樣存儲標題和摘錄。

請注意,由於所有數據都存儲在MyItem引用中,所以擴展功能以便在InfoWindow中爲每個標記顯示儘可能多的數據類型要容易得多。

首先,MyItem.java,其中包括標題和摘要額外的字段:

public class MyItem implements ClusterItem { 
    private final LatLng mPosition; 
    private final String mTitle; 
    private final String mSnippet; 

    public MyItem(double lat, double lng, String t, String s) { 
     mPosition = new LatLng(lat, lng); 
     mTitle = t; 
     mSnippet = s; 
    } 

    @Override 
    public LatLng getPosition() { 
     return mPosition; 
    } 

    public String getTitle(){ 
     return mTitle; 
    } 

    public String getSnippet(){ 
     return mSnippet; 
    } 
} 

以下是完整的活動類,其中包括所有的功能,支持每個標記信息窗口添加使用羣集庫:

編輯:添加了對處理InfoWindow上的點擊事件的支持,使Activity執行OnClusterItemInfoWindowClickListener並添加了onClusterItemInfoWindowClick回調。

public class MapsActivity extends AppCompatActivity 
     implements ClusterManager.OnClusterItemInfoWindowClickListener<MyItem> { 

    private ClusterManager<MyItem> mClusterManager; 
    private MyItem clickedClusterItem; 
    private GoogleMap mMap; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_maps); 

     setUpMapIfNeeded(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     setUpMapIfNeeded(); 
    } 


    private void setUpMapIfNeeded() { 
     // Do a null check to confirm that we have not already instantiated the map. 
     if (mMap == null) { 
      // Try to obtain the map from the SupportMapFragment. 
      mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) 
        .getMap(); 

      // Check if we were successful in obtaining the map. 
      if (mMap != null) { 
       setUpMap(); 
      } 

     } 
    } 

    private void setUpMap() { 

     mMap.getUiSettings().setMapToolbarEnabled(true); 
     mMap.getUiSettings().setZoomControlsEnabled(true); 
     mMap.setMyLocationEnabled(true); 
     mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 

     mClusterManager = new ClusterManager<>(this, mMap); 

     mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.779977,-122.413742), 10)); 

     mMap.setOnCameraChangeListener(mClusterManager); 
     mMap.setOnMarkerClickListener(mClusterManager); 

     mMap.setInfoWindowAdapter(mClusterManager.getMarkerManager()); 

     mMap.setOnInfoWindowClickListener(mClusterManager); //added 
     mClusterManager.setOnClusterItemInfoWindowClickListener(this); //added 

     mClusterManager 
       .setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() { 
        @Override 
        public boolean onClusterItemClick(MyItem item) { 
         clickedClusterItem = item; 
         return false; 
        } 
       }); 



     addItems(); 

     mClusterManager.getMarkerCollection().setOnInfoWindowAdapter(
       new MyCustomAdapterForItems()); 

    } 

    private void addItems() { 

     double latitude = 37.779977; 
     double longitude = -122.413742; 
     for (int i = 0; i < 10; i++) { 
      double offset = i/60d; 

      double lat = latitude + offset; 
      double lng = longitude + offset; 
      MyItem offsetItem = new MyItem(lat, lng, "title " + i+1, "snippet " + i+1); 
      mClusterManager.addItem(offsetItem); 

     } 

    } 

    //added with edit 
    @Override 
    public void onClusterItemInfoWindowClick(MyItem myItem) { 

     //Cluster item InfoWindow clicked, set title as action 
     Intent i = new Intent(this, OtherActivity.class); 
     i.setAction(myItem.getTitle()); 
     startActivity(i); 

     //You may want to do different things for each InfoWindow: 
     if (myItem.getTitle().equals("some title")){ 

      //do something specific to this InfoWindow.... 

     } 

    } 

    public class MyCustomAdapterForItems implements GoogleMap.InfoWindowAdapter { 

     private final View myContentsView; 

     MyCustomAdapterForItems() { 
      myContentsView = getLayoutInflater().inflate(
        R.layout.info_window, null); 
     } 
     @Override 
     public View getInfoWindow(Marker marker) { 

      TextView tvTitle = ((TextView) myContentsView 
        .findViewById(R.id.txtTitle)); 
      TextView tvSnippet = ((TextView) myContentsView 
        .findViewById(R.id.txtSnippet)); 

      tvTitle.setText(clickedClusterItem.getTitle()); 
      tvSnippet.setText(clickedClusterItem.getSnippet()); 

      return myContentsView; 
     } 

     @Override 
     public View getInfoContents(Marker marker) { 
      return null; 
     } 
    } 
} 

info_window。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:padding="20dp" 
    android:orientation="vertical" 
    android:background="#000000"> 

    <TextView 
     android:id="@+id/txtTitle" 
     android:textColor="#D3649F" 
     android:textStyle="bold" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

    <TextView 
     android:id="@+id/txtSnippet" 
     android:textColor="#D3649F" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

結果:

首次推出:

enter image description here

縮小時,啓動羣集:

enter image description here

放大了一遍,更聚類:

enter image description here

然後,放大,和單擊單個標記:

enter image description here

編輯::

enter image description here

然後在另一個標記點​​擊爲了在自定義InfoWindow周圍顯示「語音氣泡」,使用getInfoContents()代替getInfoWindow()

public class MyCustomAdapterForItems implements GoogleMap.InfoWindowAdapter { 

    private final View myContentsView; 

    MyCustomAdapterForItems() { 
     myContentsView = getLayoutInflater().inflate(
       R.layout.info_window, null); 
    } 

    @Override 
    public View getInfoWindow(Marker marker) { 
     return null; 
    } 

    @Override 
    public View getInfoContents(Marker marker) { 

     TextView tvTitle = ((TextView) myContentsView 
       .findViewById(R.id.txtTitle)); 
     TextView tvSnippet = ((TextView) myContentsView 
       .findViewById(R.id.txtSnippet)); 

     tvTitle.setText(clickedClusterItem.getTitle()); 
     tvSnippet.setText(clickedClusterItem.getSnippet()); 

     return myContentsView; 
    } 
} 

結果:

enter image description here

+0

非常感謝你的出色答案! :)我如何將InfoWindow下面的小向下箭頭添加爲正常的InfoWindow所具有的?另外我將如何添加一個onInfoWindowClickListener?用同樣的方式,我會用普通的地圖來做到這一點? – qwertz

+0

@qwertz我將不得不看看!對於信息窗口點擊,我會讓它工作並更新答案! –

+0

非常感謝您的幫助:) – qwertz

0
@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.map); 

     mClusterManager = new ClusterManager<>(this, mMap); 

     mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 

     mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10)); 
     mMap.setOnCameraChangeListener(mClusterManager); 
     mMap.setInfoWindowAdapter(new InfoWindowAdapter() { 
     /** 
     * View for displaying marker popup, if null default framework view would be used 
     */ 
     @Override 
     public View getInfoWindow(Marker marker) { 
      return null; 
     } 

     /** 
     * For changing the content of infowindow 
     * Called when showMarkerInfo method is called 
     */ 
     @Override 
     public View getInfoContents(Marker marker) { 
      View v = getLayoutInflater().inflate(R.layout.view_to_inflate, null);  
      //code for initializing view part 
      return v; 
     } 
    }); 
     readItems(); 
    } 
+0

我是否需要在MyItem類中添加標題和片段字段?如何將標題和片段添加到標記? – qwertz

+0

我想,你必須添加標題和片段 – abhishesh

0

你可以考慮以下方法:

public void initilizeMap() { 
      googleMap = mFragment.getMap(); 
      googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN); 
      googleMap.getUiSettings().setZoomControlsEnabled(true`enter code here`); // true to`enter code here` 
      googleMap.getUiSettings().setZoomGesturesEnabled(true); 
      googleMap.getUiSettings().setCompassEnabled(true); 
      googleMap.getUiSettings().setMyLocationButtonEnabled(true); 
      googleMap.getUiSettings().setRotateGesturesEnabled(true); 
      if (googleMap == null) { 
       Toast.makeText(getActivity(), "Sorry! unable to create maps", 
         Toast.LENGTH_SHORT).show(); 
      } 
      mClusterManager = new ClusterManager<MyItem>(getActivity(), googleMap); 
//   googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter()); 
      googleMap.setOnMapLoadedCallback(this); 
      googleMap.setMyLocationEnabled(true); 
      googleMap.setBuildingsEnabled(true); 
      googleMap.getUiSettings().setTiltGesturesEnabled(true); 

MyItem offsetItem = new MyItem(Double.parseDouble(outletList.get(i).getMap_latitude()), 
              Double.parseDouble(outletList.get(i).getMap_longitude()), title , address); 
      mClusterManager.addItem(offsetItem); 
      googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(offsetItem)); 

} 


    private class CustomInfoWindowAdapter implements InfoWindowAdapter { 
     Marker marker; 
     private View view; 
     private MyItem items; 

     public CustomInfoWindowAdapter(MyItem item) { 
      view = getActivity().getLayoutInflater().inflate(
        R.layout.custom_info_window, null); 
      this.items = item; 
     } 

     @Override 
     public View getInfoContents(Marker marker) { 

      if (marker != null && marker.isInfoWindowShown()) { 
       marker.hideInfoWindow(); 
       marker.showInfoWindow(); 
      } 
      return null; 
     } 

     @Override 
     public View getInfoWindow(final Marker marker) { 
      this.marker = marker; 

      String url = null; 

      if (marker.getId() != null && markers != null && markers.size() > 0) { 
       if (markers.get(marker.getId()) != null 
         && markers.get(marker.getId()) != null) { 
        url = markers.get(marker.getId()); 
       } 
      } 

      final ImageView image = ((ImageView) view.findViewById(R.id.badge)); 

      if (url != null && !url.equalsIgnoreCase("null") 
        && !url.equalsIgnoreCase("")) { 
       imageLoader.displayImage(url, image, options, 
         new SimpleImageLoadingListener() { 
          @Override 
          public void onLoadingComplete(String imageUri, 
            View view, Bitmap loadedImage) { 
           super.onLoadingComplete(imageUri, view, 
             loadedImage); 
           getInfoContents(marker); 
          } 
         }); 
      } else { 
       image.setImageResource(R.drawable.ic_launcher); 
      } 

      final String title = items.getTitle(); 
      Log.e(TAG, "TITLE : "+title); 
      final TextView titleUi = ((TextView) view.findViewById(R.id.title)); 
      if (title != null) { 
       titleUi.setText(title); 
      } else { 
       titleUi.setText(""); 
      } 

      final String address = items.getAddress(); 
      final TextView snippetUi = ((TextView) view 
        .findViewById(R.id.snippet)); 
      if (address != null) { 
       snippetUi.setText(address); 
      } else { 
       snippetUi.setText(""); 
      }