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

Flutter项目中Google Maps显示双折线而非单折线的问题求助

Flutter GoogleMap 偶尔显示多条Polyline的解决方案

问题分析

你遇到的多条Polyline异常,核心原因是异步操作的竞态条件与状态更新时机不一致:

  • 原代码中先清空Polyline集合并通知UI,再异步获取线路数据后添加新Polyline并再次通知,两次通知之间可能因快速重复调用导致旧的Polyline未被及时清除,新的已叠加显示。
  • UI层通过polyline.last获取线路,依赖Set的顺序稳定性,存在潜在风险。

解决方案

1. 合并状态更新,移除冗余通知

将清空与添加Polyline的操作合并为一次状态更新,只触发一次UI通知,避免中间状态导致的显示异常:

class MapViewProvider extends ChangeNotifier {
  Set<Polyline> polyline = {};
  
  void drawPolyline(LatLng selectedPoint) async {
    LatLng? currentPoint = chooseWhereFromDrawPolyline();
    if (currentPoint == null) return;

    List<LatLng>? latLong = await MyPolyline().getPolylinePoints(
      currentPoint,
      selectedPoint,
    );
    if (latLong == null) return;

    // 直接替换整个集合,无需分步清空与通知
    polyline = {
      Polyline(
        polylineId: const PolylineId("single_polyline"), // 固定唯一ID,确保旧线路被覆盖
        visible: true,
        points: latLong,
        geodesic: false,
        color: ColorsRes.dark500.withOpacity(.6),
        width: 5,
        startCap: Cap.roundCap,
        endCap: Cap.roundCap,
      ),
    };
    notifyListeners(); // 仅一次通知,保证状态一致性
  }
}

2. 简化UI层的Polyline传递

由于已确保集合中始终只有一条Polyline,直接传递整个集合即可,无需额外处理:

GoogleMap(
  // ... 其他属性
  polylines: _provider.polyline,
  // ... 其他属性
)

3. 添加调用锁,防止重复执行

若存在快速重复调用drawPolyline的场景,可添加锁机制避免并发异步操作导致的竞态:

class MapViewProvider extends ChangeNotifier {
  Set<Polyline> polyline = {};
  bool _isDrawing = false;

  void drawPolyline(LatLng selectedPoint) async {
    if (_isDrawing) return; // 正在绘制时拒绝新请求
    _isDrawing = true;

    try {
      LatLng? currentPoint = chooseWhereFromDrawPolyline();
      if (currentPoint == null) return;

      List<LatLng>? latLong = await MyPolyline().getPolylinePoints(
        currentPoint,
        selectedPoint,
      );
      if (latLong == null) return;

      polyline = {
        Polyline(
          polylineId: const PolylineId("single_polyline"),
          visible: true,
          points: latLong,
          geodesic: false,
          color: ColorsRes.dark500.withOpacity(.6),
          width: 5,
          startCap: Cap.roundCap,
          endCap: Cap.roundCap,
        ),
      };
      notifyListeners();
    } finally {
      _isDrawing = false; // 无论成功失败都释放锁
    }
  }
}

核心逻辑说明

  • 固定PolylineId:GoogleMap会自动替换同ID的Polyline,避免多条叠加。
  • 合并状态更新:确保UI只接收到最终的单条Polyline状态,消除中间过渡状态的干扰。
  • 调用锁:防止多次异步请求同时执行,保证状态更新的原子性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:20:19