You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中Google Map避免缩放判断致重复重组的方案

解决Jetpack Compose Google Map缩放控制标记显示时的卡顿问题

问题根源

你之前的写法每次拖动相机(zoom变化)都会触发重组,当zoom>15时会重新创建所有Marker实例,大量Marker反复实例化销毁直接导致卡顿。用derivedStateOf只是包装了判断条件,但本质还是通过重组来添加/移除Marker,没解决核心问题。

解决方案:控制Marker可见性而非动态创建/移除

核心思路是一次性创建所有Marker,通过监听缩放变化来切换它们的isVisible状态,避免重复实例化:

  1. 提前缓存资源和Marker状态
    把BitmapDescriptor和所有Marker的状态一次性初始化并记住,避免每次重组重复创建:

    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(city, 13f)
    }
    
    // 缓存图标资源,避免重复加载
    val bitmapDescriptor = remember {
        BitmapDescriptorFactory.fromResource(R.drawable.ic_bus_mini)
    }
    
    // 一次性创建所有Marker的状态,数据更新时才重新生成
    val markerStates = remember(uiState.data) {
        uiState.data.map { busStop ->
            rememberMarkerState(position = LatLng(busStop.lat, busStop.lon)) to busStop.name
        }
    }
    
  2. 监听缩放变化,动态切换Marker可见性
    用LaunchedEffect配合snapshotFlow监听zoom变化,只更新Marker的可见性,不触发重组创建新Marker:

    LaunchedEffect(cameraPositionState) {
        // 只监听zoom的变化,减少不必要的回调
        snapshotFlow { cameraPositionState.position.zoom }
            .collect { currentZoom ->
                val shouldShowMarkers = currentZoom > 15
                markerStates.forEach { (markerState, _) ->
                    markerState.isVisible = shouldShowMarkers
                }
            }
    }
    
  3. 在Map中添加所有Marker
    直接把所有Marker添加到Map里,不用if判断,通过isVisible控制显示:

    GoogleMap(modifier = Modifier.fillMaxSize(), cameraPositionState = cameraPositionState) {
        markerStates.forEach { (state, title) ->
            Marker(
                state = state,
                title = title,
                icon = bitmapDescriptor
            )
        }
    }
    

为什么这个方法有效?

  • 所有Marker只会在初始化或数据更新时创建一次,不会随相机拖动反复销毁重建
  • 只修改Marker的isVisible属性,这是轻量操作,不会引发大量重组
  • snapshotFlow精准监听zoom变化,避免无关的相机移动(比如平移)触发回调

内容的提问来源于stack exchange,提问作者NullPointerException

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:31:08