androidkotlingoogle-mapsandroid-jetpack-compose

how can GoogleMap composable be personalized?


I'm doing a project on Compose with Google Maps SDK for Android. I'm trying to customize all the UI on the map, I know that this can be done with the old library of GoogleMaps but I don't know how to do it on new compose library.

I want to change markers, remove default places markers, change font style, customize actual location button, etc... I've taken a look into Google documentation but it is very poor, the unique solution that I have found is to use the old library, but if it's the only one solution it's a pity because the new library makes all much easier.

Here is the implementation of GoogleMap into my composable:

@Composable
fun DiscoverContent(
  mapState: MapState,
  setupClusterManager: (Context, GoogleMap) -> ZoneClusterManager,
  calculateZoneViewCenter: () -> LatLngBounds,
  onClusterClicked: (ZoneClusterItem) -> Unit
) {

  val context = LocalContext.current
  val mapProperties = MapProperties(isMyLocationEnabled = mapState.lastKnownLocation != null)
  val cameraPositionState = rememberCameraPositionState()

  GoogleMap(
    modifier = Modifier.fillMaxSize(),
    properties = mapProperties,
    cameraPositionState = cameraPositionState,
    uiSettings = MapUiSettings()
  ) {

    val scope = rememberCoroutineScope()
    MapEffect(mapState.clusterItems) { map ->
      if (mapState.clusterItems.isNotEmpty()) {
        val clusterManager = setupClusterManager(context, map)
        map.setOnCameraIdleListener(clusterManager)
        map.setOnMarkerClickListener(clusterManager)
        clusterManager.setOnClusterClickListener { cluster ->
          val clusterItem = cluster.items.firstOrNull()
          clusterItem?.let { onClusterClicked(it) }
          true
        }
        map.setOnMapLoadedCallback {
          if (mapState.clusterItems.isNotEmpty()) {
            scope.launch {
              cameraPositionState.animate(
                update = CameraUpdateFactory.newLatLngBounds(
                  calculateZoneViewCenter(),
                  MAP_PADDING
                )
              )
            }
          }
        }
      }
    }
  } 

Here I upload a screenshot of how it looks right now. How map looks right now


Solution

  • I found a way to customize some aspects of GoogleMap composable. In mapProperties parameter of GoogleMap composable you can add mapStyleOptions like this

    val mapProperties = MapProperties(
        isMyLocationEnabled = mapState.lastKnownLocation != null,
        mapStyleOptions = MapStyleOptions(styleJson)
      )
    

    then you pass a .json with all thinks that you want to customize, in my case I only wanted to delete the poi markers (default markers that come in default map, like restaurants and supermarkets) and also change color of water and delete road labels. I figured it out passing this .json

    val styleJson = """
        [
            {
                "featureType": "poi",
                "elementType": "labels",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "road",
                "elementType": "labels",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "water",
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#CDE2F0"
                    }
                ]
            },
            {
                "featureType": "poi",
                "elementType": "labels.icon",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            }
        ]
    """.trimIndent()
    

    I hope it helps to all the people who is trying to implement a GoogleMap on his project!