How can I create a custom marker icon with custom text like this in compose?
Currently, I am creating this icon using pin config in advanced marker, but it causes lag, using pin config in advanced marker is not as smooth as normal marker.
Note: Bus Icon is built in map
Red Marker with 22222 text is created using
AdvancedMarker(
state = markerState,
pinConfig = marker.pinConfig,
title = "hello",
snippet = "World",
alpha = alpha,
)
I want to use this marker where I can provide the above icon to this marker function
Marker(
state = markerState,
icon =
)
I can not use the pin config in Marker(). it requires BitmapDescriptor
To create a marker as you have shown in the image you need to follow these steps.
Step 1. Create a Custom Marker Composable
@Composable
fun CustomMarkerView(text: String) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.size(100.dp)
.background(Color.Red, shape = RoundedCornerShape(50.dp))
.border(2.dp, Color.Black, shape = RoundedCornerShape(50.dp))
) {
Text(text, color = Color.White, fontSize = 16.sp)
}
}
Step 2. Convert Composable to Bitmap
fun createMarkerBitmap(context: Context, text: String): Bitmap {
// Create an empty Bitmap with a specific width, height, and config
val bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap) // Initialize a Canvas to draw on the bitmap
// Get the device screen density (to scale things correctly)
val density = context.resources.displayMetrics.density
// Create a ComposeView that will render the composable into a view
val composeView = ComposeView(context).apply {
setContent {
// Render the custom marker composable inside this ComposeView
CustomMarkerView(text = text)
}
}
// Measure and layout the ComposeView to be rendered correctly
composeView.measure(
View.MeasureSpec.makeMeasureSpec((100 * density).toInt(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec((100 * density).toInt(), View.MeasureSpec.EXACTLY)
)
composeView.layout(0, 0, composeView.measuredWidth, composeView.measuredHeight)
// Finally, draw the ComposeView on the Canvas (which is linked to the Bitmap)
composeView.draw(canvas)
return bitmap // Return the resulting Bitmap with the custom composable drawn
}
Step 3. Use BitmapDescriptor in Google Maps Marker
val customMarkerBitmap = createMarkerBitmap(context, "22222") // Create the bitmap with the desired text
val markerOptions = MarkerOptions()
.position(LatLng(0.0, 0.0)) // Set the position of the marker
.icon(BitmapDescriptorFactory.fromBitmap(customMarkerBitmap)) // Use the generated Bitmap as the icon
googleMap.addMarker(markerOptions) // Add the marker to the GoogleMap instance
How It Works:
Custom Marker Design: The CustomMarkerView
composable defines how to draw the marker. In this case, it is a red circle with a black border and centered text.
Composable to Bitmap: The function is createMarkerBitmap
. It takes this composable and renders it into a Bitmap. To do this, it uses a Canvas
that it draws it onto the Bitmap after first rendering it inside a ComposeView
.
Google Maps Marker: Next, this bitmap was converted into a BitmapDescriptor
, so that it could be used as the marker icon in Google Maps with the MarkerOptions
.
I think this method is more efficient than using the AdvancedMarker
and avoids the lag you are experiencing.