使用CameraPositionState致Google Maps冻结,如何优化手势移动后操作?
优化方案
你的代码直接在Composable的重组流程中判断相机状态,会导致地图频繁触发重组,甚至因同步执行耗时操作阻塞UI线程,进而出现冻结无响应。可以通过以下两种方式优化:
方式一:使用LaunchedEffect监听状态变化
利用LaunchedEffect在协程环境中监听相机状态,避免阻塞UI线程,仅在状态满足条件时执行目标操作:
val singapore = LatLng(1.35, 103.87) val cameraPositionState: CameraPositionState = rememberCameraPositionState { position = CameraPosition.fromLatLngZoom(singapore, 11f) } // 监听相机移动开始原因和移动状态 LaunchedEffect(cameraPositionState.cameraMoveStartedReason, cameraPositionState.isMoving) { if (cameraPositionState.isMoving && cameraPositionState.cameraMoveStartedReason == CameraMoveStartedReason.GESTURE) { // 在这里执行你的操作,比如更新数据、触发其他逻辑 // 注意:如果是耗时操作,要放在后台协程处理 } }
方式二:使用相机状态回调
直接利用Google Maps提供的相机状态回调接口,更精准地响应手势触发的相机移动事件,减少Composable重组依赖:
val singapore = LatLng(1.35, 103.87) val cameraPositionState: CameraPositionState = rememberCameraPositionState { position = CameraPosition.fromLatLngZoom(singapore, 11f) } // 初始化时添加相机状态监听器 DisposableEffect(cameraPositionState) { val moveStartedListener = CameraMoveStartedListener { reason -> if (reason == CameraMoveStartedReason.GESTURE) { // 手势开始移动时的操作 } } val idleListener = CameraIdleListener { // 手势移动结束(相机静止)时的操作,适合需要在移动完成后执行的逻辑 } cameraPositionState.addCameraMoveStartedListener(moveStartedListener) cameraPositionState.addCameraIdleListener(idleListener) // 组件销毁时移除监听器,避免内存泄漏 onDispose { cameraPositionState.removeCameraMoveStartedListener(moveStartedListener) cameraPositionState.removeCameraIdleListener(idleListener) } }
如果你的目标是在手势移动结束后执行操作,优先选择方式二中的CameraIdleListener,它会在相机停止移动时触发,更符合"移动后执行"的场景。
内容的提问来源于stack exchange,提问作者mlauth
相关产品推荐
相关产品推荐

