It seems that Airbnb simply hides/shows specific markers when the zoom level changes.
You could use Marker Clustering so markers join together into a single group when zoomed out. If that's not what you want, read on.
I answered a similar question regarding polylines here.
The solution is to create a sparse array, which for specific zoom levels, contains specific markers. E.g.:
// Zoom level 16 and up
List<Marker> markers = new ArrayList<Marker>();
markers.add(mMap.addMarker(new MarkerOptions()
.position(new LatLng(48.867068, 2.351503))));
...
// Markers are hidden by default
for (Marker marker : markers) marker.setVisible(false);
mZoomMarkers.put(16, markers);
Then initialize your map, revealing some of the markers:
SparseArray<List<Marker>> mZoomMarkers = new SparseArray<List<Marker>>();
int mZoomLevel = 16;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
// Zoom to 16
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(point, mZoomLevel), 1000, null);
// Reveal markers
for(int i=0; i<mZoomMarkers.size(); i++) {
// Loop until zoom level is reached
if (mZoomMarkers.keyAt(i) > zoomLevel) break;
showMarkers(mZoomMarkers.get(mZoomMarkers.keyAt(i)));
}
...
}
private void showMarkers(List<Marker> markers) {
if (markers != null) {
for (Marker marker : markers) marker.setVisible(true);
}
}
private void hideMarkers(List<Marker> markers) {
if (markers != null) {
for (Marker marker : markers) marker.setVisible(false);
}
}
Finally set up a zoom level listener to add/remove markers accordingly:
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
/* Note that because we are casting the zoomLevel to int,
* it will be considered as changed only when it reaches
* a new integer when rounded (e.g. 5.0, 6.0 etc.) */
int newZoomLevel = (int) cameraPosition.zoom;
if (newZoomLevel != mZoomLevel) {
Log.d(TAG, "New zoom level: " + newZoomLevel);
// Loop all the changed zoom levels
// E.g. zoomed-out from 15 to 13, then hide [14, 15]
if (newZoomLevel < mZoomLevel) { // Zoomed out
for (int i=1; i<=mZoomLevel-newZoomLevel; i++)
hideMarkers(mZoomMarkers.get(newZoomLevel + i));
} else { // Zoomed-in
for (int i=1; i<=newZoomLevel-mZoomLevel; i++)
showMarkers(mZoomMarkers.get(mZoomLevel + i));
}
mZoomLevel = newZoomLevel;
}
}
});