如何让Google Maps Compose中的Marker平滑移动而非跳跃?
解决Google Maps Compose中Marker平滑移动的问题
直接修改MarkerState.position会导致Marker瞬间跳跃到新位置,因为Google Maps Compose的Marker本身没有内置位置过渡动画。要实现平滑移动,需要借助Compose的动画系统对经纬度进行插值,再实时同步到Marker上。
核心思路
- 使用
Animatable管理经纬度的动画插值,它能自动计算两个数值之间的过渡中间值 - 每次更新目标位置时,启动动画让经纬度从当前值平滑过渡到新值
- 监听动画值的变化,实时同步到Marker的位置
修改后的完整代码
val marker1 = rememberMarkerState(key = "1", position = LatLng(10.0, 10.0)) // 初始化动画用的经纬度值,与Marker初始位置保持一致 val animatedLat = remember { Animatable(marker1.position.latitude) } val animatedLng = remember { Animatable(marker1.position.longitude) } val scope = rememberCoroutineScope() LaunchedEffect(key1 = Unit) { while (true) { // 计算本次要移动到的目标位置 val targetLat = marker1.position.latitude + 0.001 val targetLng = marker1.position.longitude + 0.001 // 启动经纬度的平滑动画,durationMillis控制移动速度 launch { animatedLat.animateTo( targetValue = targetLat, animationSpec = tween(durationMillis = 500) ) } launch { animatedLng.animateTo( targetValue = targetLng, animationSpec = tween(durationMillis = 500) ) } // 监听动画值变化,实时更新Marker位置 snapshotFlow { Pair(animatedLat.value, animatedLng.value) } .collect { (lat, lng) -> marker1.position = LatLng(lat, lng) } delay(5000) // 5秒后触发下一次位置更新 } } GoogleMap( modifier = modifier, cameraPositionState = cameraPositionState, properties = mapProperties, uiSettings = uiSettings, onMapLoaded = onMapLoaded, ) { Marker(state = marker1) content() }
关键细节说明
- 动画类型选择:示例中用
tween实现匀速过渡,若要更自然的物理运动效果,可替换为spring动画,比如:animationSpec = spring(stiffness = Spring.StiffnessLow) - 动画时长调整:
durationMillis值越小,Marker移动速度越快;值越大则移动越平缓,可根据需求自行修改 - 避免动画冲突:当前代码中
delay(5000)远大于动画时长500ms,不会出现叠加动画。若需更频繁的位置更新,建议添加状态判断,确保前一次动画完成后再启动新动画
内容的提问来源于stack exchange,提问作者RCH
相关产品推荐
相关产品推荐

