2015-06-20 52 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(""); 
      }