Many developers, when building location-based applications that use Google Maps, face the problem of displaying a large number of different types of markers.

Today we’ll learn how:

to use clustering

to create custom icons for clusters and markers

to detect cluster marker click

to create a custom popup on a marker click

Let’s get started.

Suppose we write an application to search for the nearest hotels, and we want to create building icons for each marker. Or we need to create a map of stores with discounts offered in them, and the map marker with an amount of a discount.

First of all, you need to add a dependency in your build.gradle:

compile 'com.google.android.gms:play-services-maps:9.0.2'

compile 'com.google.maps.android:android-maps-utils:0.4.3'

Secondly, we create new Activity:

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback { private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_maps); final SupportMapFragment mapFragment =

(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

mapFragment.getMapAsync(this);

} @Override public void onMapReady(GoogleMap googleMap) {

mMap = googleMap;

}

}

activity_maps.xml:

<fragment

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/map"

android:name="com.google.android.gms.maps.SupportMapFragment"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="io.github.tonyshkurenko.clustermanagerdemo.MapsActivity"

/>

Then we create static nested class that will store a title and the position of the marker, implementing ClusterItem interface:

static class StringClusterItem implements ClusterItem { final String title;

final LatLng latLng; public StringClusterItem(String title, LatLng latLng) {

this.title = title;

this.latLng = latLng;

} @Override public LatLng getPosition() {

return latLng;

}

}

Add a field in the MapsActivity class:

private ClusterManager<StringClusterItem> mClusterManager; @Override public void onMapReady(GoogleMap googleMap) {

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

mMap.setOnCameraChangeListener(mClusterManager);

}

Add markers:

for (int i = 0; i < 10; i++) {

final LatLng latLng = new LatLng(-34 + i, 151 + i);

mClusterManager.addItem(new StringClusterItem("Marker #" + (i + 1), latLng));

} mClusterManager.cluster();

And run the code: