Skip to content

Instantly share code, notes, and snippets.

@yaroslav-android
Created March 18, 2019 10:42
Show Gist options
  • Save yaroslav-android/7c72a12d5661ea3b5dc672bab50520d5 to your computer and use it in GitHub Desktop.
Save yaroslav-android/7c72a12d5661ea3b5dc672bab50520d5 to your computer and use it in GitHub Desktop.
Cluster Renderer for Google Map
class ClusterRender(
private val context: Context,
map: GoogleMap,
clusterManager: ClusterManager<MapClusterItem>
) : DefaultClusterRenderer<MapClusterItem>(context, map, clusterManager) {
private val factory: IconGenerator = IconGenerator(context)
private var selectedPinColor = -1
private var unselectedPinColor = -1
private var currentZoomLevel = -1f
init {
this.minClusterSize = MIN_CLUSTER_SIZE
selectedPinColor = ContextCompat.getColor(context, R.color.colorSelectedPin)
unselectedPinColor = ContextCompat.getColor(context, R.color.colorBlue)
}
override fun onBeforeClusterItemRendered(
clusterItem: MapClusterItem?,
markerOptions: MarkerOptions?
) {
if (clusterItem != null && markerOptions != null) {
markerOptions?.apply {
icon(null)
factory.setTextAppearance(context, R.style.TextAppearanceWhiteOnMap)
if (clusterItem?.isSelected) {
factory.setColor(selectedPinColor)
} else {
factory.setColor(unselectedPinColor)
}
anchor(factory.anchorU, factory.anchorV)
position(clusterItem?.position)
}
}
super.onBeforeClusterItemRendered(clusterItem, markerOptions)
}
override fun onClusterItemRendered(clusterItem: MapClusterItem?, marker: Marker?) {
marker?.let {
it.setIcon(null)
// TODO: track changes, it may crash at marker.setIcon() even with null checks
// https://github.com/googlemaps/android-maps-utils/issues/63
// Workaround --> UPDATE: not helpful
if (marker.tag == null) {
marker.tag = MARKER_TAG
}
}
onClusterItemChange(clusterItem, marker)
super.onClusterItemRendered(clusterItem, marker)
}
override fun shouldRenderAsCluster(cluster: Cluster<MapClusterItem>?): Boolean {
val isZoomLevelSuites = currentZoomLevel < MAX_ZOOM_LVL - POINT_ZOOM_LVL
return super.shouldRenderAsCluster(cluster) && isZoomLevelSuites
}
override fun getColor(clusterSize: Int): Int {
return ContextCompat.getColor(context, R.color.colorBlue)
}
fun setCurrentZoomLevel(zoomLevel: Float) {
currentZoomLevel = zoomLevel
}
fun onClusterItemChange(clusterItem: MapClusterItem?, marker: Marker?) {
if (clusterItem != null && marker != null) {
factory.setTextAppearance(context, R.style.TextAppearanceWhiteOnMap)
if (clusterItem?.isSelected) {
factory.setColor(selectedPinColor)
} else {
factory.setColor(unselectedPinColor)
}
marker?.title = clusterItem?.title
if (marker?.tag != null) {
marker?.setIcon(BitmapDescriptorFactory.fromBitmap(factory.makeIcon("${marker?.title}")))
}
}
}
companion object {
const val DOT_ZOOM_LVL = 1.5f
const val POINT_ZOOM_LVL = 3f
const val MIN_CLUSTER_SIZE = 4
const val MARKER_TAG = "marker-tag"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment