When an animation occurs and is cancelled (and in other circumstances that I did not manage to reproduce), the CameraPositionState gets corrupted and a drag gesture on the map doesn't work anymore as intended. Here is a code to reproduce the bug (click several times on the button and try to move the map, zoom is not affected somehow).
class RecompositionActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val cameraPositionState = rememberCameraPositionState {
position = defaultCameraPosition
}
Box(Modifier.fillMaxSize()) {
MapsComposeSampleTheme {
GoogleMapView(
modifier = Modifier.matchParentSize(),
cameraPositionState = cameraPositionState
)
}
}
}
}
@Composable
fun GoogleMapView(
modifier: Modifier = Modifier,
cameraPositionState: CameraPositionState = rememberCameraPositionState(),
content: @Composable () -> Unit = {},
) {
var location by remember { mutableStateOf(singapore) }
var zoom by remember { mutableStateOf(5f) }
val context = LocalContext.current
val singaporeState = MarkerState(position = location)
val mapProperties = remember {
MapProperties(
isBuildingEnabled = false,
isIndoorEnabled = false,
isMyLocationEnabled = false,
isTrafficEnabled = false,
mapType = MapType.SATELLITE,
)
}
val mapOptions = remember {
GoogleMapOptions()
.ambientEnabled(false)
.mapToolbarEnabled(false)
.compassEnabled(false)
}
val uiSettings = remember {
MapUiSettings(
compassEnabled = false,
indoorLevelPickerEnabled = false,
mapToolbarEnabled = false,
myLocationButtonEnabled = false,
rotationGesturesEnabled = false,
scrollGesturesEnabledDuringRotateOrZoom = false,
tiltGesturesEnabled = false,
zoomControlsEnabled = false,
)
}
val mapVisible by remember { mutableStateOf(true) }
if (mapVisible) {
LaunchedEffect(zoom) {
try {
cameraPositionState.animate(
update = CameraUpdateFactory.newCameraPosition(
CameraPosition(
cameraPositionState.position.target,
zoom,
0f,
0f
),
), durationMs = 1000
)
} catch(e: CancellationException) {
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
} catch(e: Exception) {
Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show()
}
}
// Detect when the map starts moving and print the reason
LaunchedEffect(cameraPositionState.isMoving) {
if (cameraPositionState.isMoving) {
Log.d(TAG, "Map camera started moving due to ${cameraPositionState.cameraMoveStartedReason.name}")
}
}
GoogleMap(
modifier = modifier.fillMaxSize(),
cameraPositionState = cameraPositionState,
googleMapOptionsFactory = {mapOptions},
onMapLoaded = {},
properties = mapProperties,
uiSettings = uiSettings,
onPOIClick = {
Log.d(TAG, "POI clicked: ${it.name}")
}
) {
val markerClick: (Marker) -> Boolean = {
Log.d(TAG, "${it.title} was clicked")
cameraPositionState.projection?.let { projection ->
Log.d(TAG, "The current projection is: $projection")
}
false
}
Marker(
state = singaporeState,
title = "Marker in Singapore",
onClick = markerClick
)
content()
}
Column {
Button(onClick = {
val randomValue = Random.nextInt(3)
location = when (randomValue) {
0 -> singapore
1 -> singapore2
2 -> singapore3
else -> singapore
}
zoom = when (randomValue) {
0 -> 3f
1 -> 6f
2 -> 15f
else -> 16f
}
}) {
Text("Change Location & Zoom")
}
}
}
}
}
android-maps-compose 4.3.0
When an animation occurs and is cancelled (and in other circumstances that I did not manage to reproduce), the CameraPositionState gets corrupted and a drag gesture on the map doesn't work anymore as intended. Here is a code to reproduce the bug (click several times on the button and try to move the map, zoom is not affected somehow).
Environment details
Steps to reproduce
Code example
Thanks by advance!