Hello all, wondering if someone can help with some...
# compose
b
Hello all, wondering if someone can help with some issues I am having with google map animation using the Google Compose Maps SDK. Code in comments.
I would like to animate my map from an origin to a destination. The origin comes from a DataStore as that is where I am saving the users last map location. The destination is passed to the MapScreen.
Copy code
data class Location(val latitude: Double, val longitude: Double)
@OptIn(MapsComposeExperimentalApi::class)
@Composable
private fun MapScreen(mapDestination : Location? = null) {
   val mapOrigin by viewModel.mapOrigin.observeAsState()

   // Pass both the origin and destination to the maps composable
   Map(mapOrigin, mapDestination)
}
Copy code
@OptIn(MapsComposeExperimentalApi::class)
@Composable
private fun Map(
  origin: Location?,
  destination: Location?
) {
   val cameraPositionState: CameraPositionState = rememberCameraPositionState {}

   LaunchedEffect(origin) {
      origin?.let { origin ->
         cameraPositionState.position = CameraPosition.fromLatLngZoom(LatLng(origin.latitude, origin.longitude), origin.zoom.toFloat())
      }
   }

   LaunchedEffect(destination) {
      destination?.let { destination ->
         scope.launch {
            val update = CameraUpdateFactory.newLatLngZoom(LatLng(destination.latitude, destination.longitude), destination.zoom.toFloat())
            cameraPositionState.animate(update)
         }
      }
   }
}
When launching the MapScreen from another composable with a new destination starting at the origin and animating to the destination works ~75% of the time. Possibly the map origin from the data store is coming in after the destination from the DataStore’s flow. Am I even in on the right track with thinking in compose on this one?
c
what you say about the order of getting the 2 values causing troubles makes sense. Why dont you add logs to your
MapScreen
so you can make sure if the bug is caused by it, or not.
If it is possible then pass both parameters to your MapScreen, so you can initialize it at you origin and then start the animation to your destination. Or you could wait until the origin parameter becomes available, before starting the animation
Something like this might work also
Copy code
if (origin != null && destination != null) {
   LaunchedEffect(Unit) {
      cameraPositionState.position = CameraPosition.fromLatLngZoom(LatLng(origin.latitude, origin.longitude), origin.zoom.toFloat())

      val update = CameraUpdateFactory.newLatLngZoom(LatLng(destination.latitude, destination.longitude), destination.zoom.toFloat())
      cameraPositionState.animate(update)
   }
}
b
Great ideas, I was looking at some logging to confirm. Want to make sure I was thinking about this correctly and not doing anything really dumb in compose. Still the case as I am a newb ;)
Ok, so I don’t think what I was seeing based on logging was due to the origin coming in after the destination (although I should probably account for origin coming in after destination). I did try your idea with nulls check and one LaunchEffect. Unfortunately I am having the exact same issue, sometimes it works, sometimes not.
c
you might need to wait for the MapView to be fully initialized before you can animate it
👍 1
b
Perfect, updated and have not seen the issue since. Thanks so much!
c
awesome 🙂 glad it helped
🍻 1
c
@Billy Newman using the GoogleMap composable instead of AndroidView? How is that working out for you???
b
@Colton Idle working great! Just heed gotchas in docs and it's fine. Took me 10 minutes to switch things out.
K 1
c
@Chris Arriola some good news for ya to read. 😄 ^
🙌 1
c
awesome! glad that’s working out. lmk if you run into any issues. thanks @Colton Idle for the ping