2015-06-20 8 views
7

Ich plane, das Google Maps-Marker-Clustering in der utils-Bibliothek zu verwenden, aber die Google Beispiel-App zeigt nur Marker-Cluster ohne infoWindow. Ich frage mich jetzt, kann ich nicht ein InfoWindow zeigen? Ich möchte, dass das InfoWindow wie mit einem normalen Google Maps-Marker auf dem Marker angezeigt wird, nicht auf dem Cluster.Android Maps Utils Clustering zeigen InfoWindow

Der Code, den ich habe: (Aus dem Beispiel google)

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

wie folgt aussieht helfen könnten: http://stackoverflow.com/questions/25968486/how-to-add-info-window-für-clustering-marker-in-android –

+0

@DanielNugent soweit ich verstanden habe, der Link gab mir erklärte, wie man ein I hinzufügen nfoWindow für den gesamten Cluster. Ich möchte ein normales InfoWindow auf einem einzelnen Marker anzeigen, wenn ich darauf klicke, wie die normale Google Map tut es – qwertz

Antwort

23

Hier ist eine vereinfachte und leicht Lösung auf this answer Basis modifiziert. Beachten Sie, dass die verknüpfte Antwort ein InfoWindow für Marker und Cluster implementiert.

Diese Lösung implementiert nur InfoWindows for Markers.

Es ähnelt der Implementierung eines benutzerdefinierten InfoWindowAdapter für normale Marker ohne Clustering, aber mit der zusätzlichen Anforderung, dass Sie einen Verweis auf das aktuell ausgewählte Objekt behalten, damit Sie den Titel und das Snippet aus seiner MyItem Instanz abrufen können. Da der Marker den Titel und das Snippet nicht wie gewöhnlich speichert.

Da alle Daten in MyItem Referenzen gespeichert sind, ist es viel einfacher, die Funktionalität so zu erweitern, dass im InfoWindow für jeden Marker so viele Datentypen angezeigt werden, wie Sie möchten.

Zuerst wird die MyItem.java, die für Titel und Snippet zusätzliche Felder enthält:

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; 
    } 
} 

Hier ist die vollständige Aktivitätsklasse, die alle Funktionen enthält Infofenster für jeden Marker zur Unterstützung hinzugefügt mit dem Cluster Bibliothek:

Bearbeiten: Zusätzliche Unterstützung für die Handhabung von Klickereignissen auf dem InfoWindow, machte die Aktivität implementieren OnClusterItemInfoWindowClickListener und fügte die onClusterItemInfoWindowClick Callback hinzu.

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> 

Ergebnis:

Ersteinführung:

enter image description here

Auszoomen, beginnt Clustering:

enter image description here

Zooming wieder heraus, mehr Clustering:

enter image description here

Dann zoomen, und klicken Sie auf einen einzelnen Marker:

enter image description here

Dann auf einem anderen Marker klicken:

enter image description here

Edit: Um zu Zeigen Sie die "Sprechblase" um das benutzerdefinierte InfoWindow, verwenden Sie statt 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; 
    } 
} 

Ergebnis:

enter image description here

+0

Vielen Dank für Ihre ausgezeichnete Antwort! :) Wie würde ich den kleinen Abwärtspfeil unter dem InfoWindow hinzufügen, wie es das normale InfoWindow hat? Wie würde ich auch einen onInfoWindowClickListener hinzufügen? So wie ich es mit einer normalen Karte machen würde? – qwertz

+0

@qwertz Ich werde mich darum kümmern müssen! Für das Info-Fenster klicken, ich werde es funktionieren und aktualisieren Sie die Antwort! –

+0

Vielen Dank für die Hilfe :) – 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

Müsste ich ein Titel- und Snippet-Feld in der MyItem-Klasse hinzufügen? Wie füge ich dem Marker einen Titel und ein Snippet hinzu? – qwertz

+0

Ich denke, Sie müssen Titel und Schnipsel hinzufügen – abhishesh

0

Sie könnten die folgende Vorgehensweise beachten:

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(""); 
      }