user924
user924

Reputation: 12195

How to add a floating card beside the start or end point of the route with Google Maps Compose?

So I have created a marker and route with Google Maps which is super easy in Compose:

GoogleMap(
    modifier = Modifier.fillMaxSize(),
    cameraPositionState = cameraPositionState,
    properties = MapProperties(
        isMyLocationEnabled = true
    ),
) {
    Marker(
        state = markerState,
        title = "Drop Off",
    )
    if (route.isNotEmpty()) {
        val bitmapDescriptor = remember {
            bitmapDescriptorFromVector(context, R.drawable.ic_point)
        }
        Polyline(
            points = route,
            color = Color(0xFF1868D2),
            width = 14f,
        )
        Polyline(
            points = route,
            startCap = CustomCap(bitmapDescriptor),
            endCap = CustomCap(bitmapDescriptor),
            color = Color(0xFF00B0FF),
            width = 10f,
        )
    }
 }

But on the design I also have a floating card beside the start and end point of the route which displays some info (time, distance).

How I can implement this type of UI on the map?

enter image description here

Upvotes: 0

Views: 378

Answers (1)

user924
user924

Reputation: 12195

Found a solution with MarkerInfoWindow but need to callmarkerState.showInfoWindow() to make it always visible on the map instead of showing it only on a marker click:

val markerState = rememberMarkerState(
    key = "pickUp",
    position = pickUpLocation
)
LaunchedEffect(key1 = markerState) {
    markerState.showInfoWindow()
}
LaunchedEffect(key1 = pickUpLocation) {
    markerState.position = pickUpLocation
}
MarkerInfoWindow(
    state = markerState,
    title = "Pick Up",
    snippet = "",
    infoWindowAnchor = Offset(-1f, 0.0f),
) {
    Card {
        Text(text = "test", color = Color.Black)
    }
}

Update actually this solution didn't work for me because I need to show two floating cards (pick up and drop off markers) but this solution allows to display only one window for one marker.

It seems I can't find any other solution how to do it...

So I guess the only way is to use Marker and convert View to Bitmap to create BitmapDescription from it to set everything as icon

View solution for Composable Google Maps Marker:

  1. Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#000"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:text="Test" />

</LinearLayout>
  1. View to Bitmap:
private fun createBitmapFromLayout(view: View): Bitmap {
    val spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
    view.measure(spec, spec)
    view.layout(0, 0, view.measuredWidth, view.measuredHeight)
    val b = Bitmap.createBitmap(
        view.measuredWidth, view.measuredHeight,
        Bitmap.Config.ARGB_8888
    )
    val c = Canvas(b)
    view.draw(c)
    return b
}
  1. In Google Maps composable:
val context = LocalContext.current
Marker(
    state = markerState,
    icon = remember {
        View.inflate(context, R.layout.marker_layout, null).let {
            BitmapDescriptorFactory.fromBitmap(createBitmapFromLayout(it))
        }
    }
)

enter image description here

Upvotes: 0

Related Questions