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

Flutter使用Animarker无法清除地图标记、clearMarkers方法未定义问题

问题根因

两个核心问题导致标记累加、无法清除:

  1. Completer<GoogleMapController>是异步获取控制器实例的包装对象,本身不存在clearMarkers方法,直接调用必然报错。
  2. Animarker插件内部单独维护了标记动画状态缓存,在原有_storeMarkers集合上做clear、add操作属于同引用修改,setState触发重建时,插件无法正确对比出标记集合的全量变化,旧标记缓存不会被回收;且Animarker的标记由插件自行绘制维护,原生google_maps_flutter的清标记方法对它无效。
修复方案

按以下步骤调整代码即可解决:

  • 修正控制器调用逻辑
    不要直接操作_mapController这个Completer实例,需要调用地图控制器方法时,必须先await拿到真实的GoogleMapController实例:
    // 新增获取真实控制器的方法
    Future<GoogleMapController> get _realMapController => _mapController.future;
    
    // 调用示例:需要移动视角、操作地图时,在async方法内获取实例
    // final controller = await _realMapController;
    // controller.animateCamera(...);
    
  • 重构标记更新逻辑,不要复用旧集合引用
    不要在原Set对象上做增删操作,每次切换轮播项时直接生成全新的Set集合赋值给_storeMarkers,保证状态对比时能检测到集合的完整变化:
    // 先定义一个变量记录当前选中的门店id,用于绑定组件key
    String? _currentShowStoreId;
    
    void _carouselCallback(Product product) {
      _currentShowStoreId = product.store?.id;
      // 直接生成新Set替换原有集合,不要在旧集合上clear/add
      _storeMarkers = {
        RippleMarker(
          markerId: MarkerId('${product.store?.id}'),
          alpha: 1,
          icon: _storePin ?? BitmapDescriptor.defaultMarker,
          position: LatLng(product.store?.lat ?? 0, product.store?.long ?? 0),
          ripple: false,
          onTap: () {
            if (product.store != null) {
              _carouselModePinCallback(product.store);
            }
          },
        )
      };
      _moveToStore(product.store);
      setState(() {});
    }
    
  • 给Animarker组件绑定值Key,强制切换标记时重置内部状态
    给Animarker加和当前展示门店绑定的Key,切换轮播项时Key变化会触发组件重建,自动清空内部缓存的旧标记,从根源避免累加问题:
    Animarker(
      // 绑定和当前展示内容关联的key
      key: ValueKey('animarker_store_${_currentShowStoreId ?? "init"}'),
      mapId: _mapController.future.then<int>((value) => value.mapId),
      rippleRadius: 0.6,  //[0,1.0] range, how big is the circle
      rippleColor: Colors.grey, // Color of fade ripple circle
      rippleDuration: Duration(milliseconds: 2500),
      markers: _storeMarkers, // 本身是Set类型,不需要额外调用toSet()
      runExpressAfter: 1, 
      // 其余原有配置参数保持不变
    )
    

注意:不要尝试调用GoogleMapController原生的标记清除方法处理Animarker的标记,这类标记由插件独立绘制管理,原生方法无法识别,反而会造成状态错乱。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:54:23