diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt b/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt index 77d2c3f2..86f30040 100644 --- a/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt +++ b/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt @@ -27,11 +27,14 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.NonRestartableComposable +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCompositionContext import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode @@ -114,33 +117,34 @@ public fun GoogleMap( it.onMyLocationClick = onMyLocationClick it.onPOIClick = onPOIClick } - val currentContentDescription by rememberUpdatedState(contentDescription) - val currentLocationSource by rememberUpdatedState(locationSource) - val currentCameraPositionState by rememberUpdatedState(cameraPositionState) - val currentContentPadding by rememberUpdatedState(contentPadding) - val currentUiSettings by rememberUpdatedState(uiSettings) - val currentMapProperties by rememberUpdatedState(properties) + + val mapUpdaterState = remember { + MapUpdaterState( + mergeDescendants, + contentDescription, + cameraPositionState, + contentPadding, + locationSource, + properties, + uiSettings + ) + }.also { + it.mergeDescendants = mergeDescendants + it.contentDescription = contentDescription + it.cameraPositionState = cameraPositionState + it.contentPadding = contentPadding + it.locationSource = locationSource + it.mapProperties = properties + it.mapUiSettings = uiSettings + } val parentComposition = rememberCompositionContext() val currentContent by rememberUpdatedState(content) + LaunchedEffect(Unit) { disposingComposition { mapView.newComposition(parentComposition, mapClickListeners) { - MapUpdater( - mergeDescendants = mergeDescendants, - contentDescription = currentContentDescription, - cameraPositionState = currentCameraPositionState, - contentPadding = currentContentPadding, - locationSource = currentLocationSource, - mapProperties = currentMapProperties, - mapUiSettings = currentUiSettings, - ) - - MapClickListenerUpdater() - - CompositionLocalProvider( - LocalCameraPositionState provides currentCameraPositionState, - ) { + Subcomposition(mapUpdaterState) { currentContent?.invoke() } } @@ -148,6 +152,41 @@ public fun GoogleMap( } } +@NonRestartableComposable +@Composable +private fun Subcomposition( + mapUpdaterState: MapUpdaterState, + content: @Composable @GoogleMapComposable () -> Unit +) { + MapUpdater(mapUpdaterState) + + MapClickListenerUpdater() + + CompositionLocalProvider( + LocalCameraPositionState provides mapUpdaterState.cameraPositionState, + content + ) +} + +@Stable +internal class MapUpdaterState( + mergeDescendants: Boolean, + contentDescription: String?, + cameraPositionState: CameraPositionState, + contentPadding: PaddingValues, + locationSource: LocationSource?, + mapProperties: MapProperties, + mapUiSettings: MapUiSettings +) { + var mergeDescendants by mutableStateOf(mergeDescendants) + var contentDescription by mutableStateOf(contentDescription) + var cameraPositionState by mutableStateOf(cameraPositionState) + var contentPadding by mutableStateOf(contentPadding) + var locationSource by mutableStateOf(locationSource) + var mapProperties by mutableStateOf(mapProperties) + var mapUiSettings by mutableStateOf(mapUiSettings) +} + internal suspend inline fun disposingComposition(factory: () -> Composition) { val composition = factory() try { diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt b/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt index f27a000d..3a331efe 100644 --- a/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt +++ b/maps-compose/src/main/java/com/google/maps/android/compose/MapUpdater.kt @@ -25,7 +25,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.LayoutDirection import com.google.android.gms.maps.GoogleMap -import com.google.android.gms.maps.LocationSource internal class MapPropertiesNode( val map: GoogleMap, @@ -93,15 +92,7 @@ internal val NoPadding = PaddingValues() @SuppressLint("MissingPermission") @Suppress("NOTHING_TO_INLINE") @Composable -internal inline fun MapUpdater( - mergeDescendants: Boolean = false, - contentDescription: String?, - cameraPositionState: CameraPositionState, - contentPadding: PaddingValues = NoPadding, - locationSource: LocationSource?, - mapProperties: MapProperties, - mapUiSettings: MapUiSettings, -) { +internal inline fun MapUpdater(mapUpdaterState: MapUpdaterState) = with(mapUpdaterState) { val map = (currentComposer.applier as MapApplier).map val mapView = (currentComposer.applier as MapApplier).mapView if (mergeDescendants) {