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

Flutter Google Maps 点击Marker后动态切换选中图标不生效问题求解

问题原因

markers 集合仅在 initState 初始化阶段生成了一次,后续 _currentIndex 变更调用 setState 时,没有重新生成带有正确 icon 属性的 Marker 集合,GoogleMap 组件拿到的始终是初始的静态 Marker 配置,因此不会触发图标更新。

解决方法

把 Marker 构建逻辑抽为动态计算的属性,每次页面重绘时都会根据最新的 _currentIndex 生成对应状态的 Marker 集合,修改后的完整代码如下:

CameraPosition _productLocation;
int _currentIndex = 0;
final Completer<GoogleMapController> _controller = Completer();

BitmapDescriptor defaultIcon =
    BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed); //default marker
BitmapDescriptor selectedIcon =
    BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueViolet); //selected marker

// 动态计算markers集合,每次获取都会用最新的_currentIndex生成对应图标
Set<Marker> get markers {
  Set<Marker> tempMarkers = {};
  if (widget.productList.isEmpty) return tempMarkers;
  widget.productList.asMap().forEach((index, v) {
    Marker resultMarker = Marker(
        icon: _currentIndex == index ? selectedIcon : defaultIcon,
        consumeTapEvents: true,
        markerId: MarkerId(v.slug),
        position: LatLng(double.parse(v.latitude), double.parse(v.longitude)),
        onTap: () {
          setState(() {
            _currentIndex = index;
          });
          buttonCarouselController.animateToPage(index);
        });
    tempMarkers.add(resultMarker);
  });
  return tempMarkers;
}

@override
void initState() {
  super.initState();
  _productLocation = const CameraPosition(
    target: LatLng(0, 0),
    zoom: 16,
  );
}

@override
Widget build(BuildContext context) {
  size = Screen(MediaQuery.of(context).size);
  return Scaffold(
    backgroundColor: Colors.white,
    extendBodyBehindAppBar: true,
    body: SizedBox.expand(
      child: GoogleMap(
        markers: markers,
        mapType: MapType.normal,
        initialCameraPosition: _productLocation,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
    ),
  );
}

优化说明

如果你的商品列表数量非常多,全量重新生成 Marker 有性能损耗,可以只在点击 Marker 时更新前后两个状态变化的 Marker:点击时先移除旧的选中态和新的普通态Marker,再把两个的 icon 互换后重新加入集合,再调用 setState 即可,常规场景下上面的全量生成方案完全够用,代码更易维护。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 20:36:05