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

MarkerComposable(谷歌地图)在Compose中不触发Image组件重组问题

MarkerComposable点击后Image不更新的问题分析与解决

问题成因

你遇到的核心问题是MarkerComposable的内容lambda运行在独立的子Composition中,这个子Composition默认不会监听外部可组合函数(MyMarker)中的状态变化。虽然你在MyMarker里定义了iconSelected状态,点击时也正确修改了值,但MarkerComposable的content lambda不会感知到这个状态更新——它只会在MarkerComposable初始化时执行一次,之后不会自动重组。而title参数能更新是因为它是MarkerComposable的直接入参,参数变化会触发组件本身的重组,但content lambda是独立的逻辑块,不受这个影响。

修复现有代码的方案

要让content里的Image响应iconSelected变化,你需要让content lambda能捕获到状态的最新值,有两种简单方法:

方法1:用rememberUpdatedState包装状态

在content lambda内部,用rememberUpdatedState获取最新的iconSelected值,这样当外部状态变化时,这个包装后的State会通知重组:

@Composable
private fun MyMarker(
    location: Location,
    onPinClick: () -> Unit,
) {
    val markerState = rememberMarkerState(
        position = location.toLatLng(),
    )
    var iconSelected by rememberSaveable { mutableStateOf(false) }
    // 包装状态,让content能感知变化
    val updatedIconSelected = rememberUpdatedState(iconSelected)
    
    MarkerComposable(
        state = markerState,
        title = if (iconSelected) "true" else "false",
        onClick = { _ ->
            iconSelected = !iconSelected
            false
        },
    ) {
        Image(
            painter = painterResource(
                if (updatedIconSelected.value) {
                    R.drawable.low_availability_selected_pin
                } else {
                    R.drawable.high_availability_fav_pin
                },
            ),
            contentDescription = null,
        )
    }
}

方法2:给MarkerComposable添加key参数

通过给MarkerComposable设置key参数,当iconSelected变化时,强制MarkerComposable重新创建,从而触发content lambda的重组:

MarkerComposable(
    state = markerState,
    title = if (iconSelected) "true" else "false",
    onClick = { _ ->
        iconSelected = !iconSelected
        false
    },
    key = iconSelected // 状态变化时强制重组
) {
    Image(
        painter = painterResource(
            if (iconSelected) {
                R.drawable.low_availability_selected_pin
            } else {
                R.drawable.high_availability_fav_pin
            },
        ),
        contentDescription = null,
    )
}

替代方案:使用普通Marker组件

如果MarkerComposable的行为不符合预期,你可以改用谷歌地图官方的普通Marker组件,通过切换icon参数的BitmapDescriptor来实现样式变更,这种方式更稳定,文档也更完善:

@Composable
private fun MyMarker(
    location: Location,
    onPinClick: () -> Unit,
) {
    val markerState = rememberMarkerState(
        position = location.toLatLng(),
    )
    var iconSelected by rememberSaveable { mutableStateOf(false) }
    // 根据状态创建对应的BitmapDescriptor
    val markerIcon = remember(iconSelected) {
        if (iconSelected) {
            BitmapDescriptorFactory.fromResource(R.drawable.low_availability_selected_pin)
        } else {
            BitmapDescriptorFactory.fromResource(R.drawable.high_availability_fav_pin)
        }
    }
    
    Marker(
        state = markerState,
        title = if (iconSelected) "true" else "false",
        icon = markerIcon,
        onClick = { _ ->
            iconSelected = !iconSelected
            false
        },
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:30:23