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

Flutter Google Maps:无需点击Marker即可显示所有InfoWindow标题

解决google_maps_flutter地图加载完成后自动显示所有Marker的InfoWindow问题

首先要明确两个核心点:

  • 原生Android/iOS地图SDK默认仅支持同时显示一个InfoWindow,显示新的会自动关闭已打开的。如果要同时展示多个,只能通过自定义组件实现。
  • 你提供的代码存在两处问题:方法名拼写错误(_onCameraIde应为_onCameraIdle),且调用时机不对——地图刚创建时Marker可能还未完成渲染,直接调用showMarkerInfoWindow会无效。

方案1:依次显示InfoWindow(原生支持)

如果接受一次显示一个InfoWindow(或依次轮显),可以按以下步骤实现:

  1. 正确获取MapController,在onMapCreated回调中完成初始化:
Completer<GoogleMapController> _controller = Completer();

// GoogleMap组件配置
GoogleMap(
  onMapCreated: (GoogleMapController controller) {
    _controller.complete(controller);
    // 地图创建完成后延迟片刻,确保Marker渲染完毕再执行
    Future.delayed(const Duration(milliseconds: 500), _showAllInfoWindows);
  },
  markers: markerSet,
  initialCameraPosition: const CameraPosition(target: LatLng(37.7749, -122.4194), zoom: 12),
  // 其他地图配置...
)
  1. 实现批量显示InfoWindow的方法,用for循环+await确保每个调用生效:
void _showAllInfoWindows() async {
  final mapController = await _controller.future;
  for (final marker in markerSet) {
    await mapController.showMarkerInfoWindow(marker.markerId);
    // 可选:添加小延迟避免频繁调用导致的异常
    await Future.delayed(const Duration(milliseconds: 100));
  }
}

方案2:同时显示多个自定义InfoWindow(原生不支持,需自定义)

如果需要同时展示所有Marker的标题,只能通过在地图上层叠加自定义文本组件实现:

  1. 准备存储Marker位置和标题的列表(从markerSet转换):
List<Map<String, dynamic>> _markerInfos = [];

// 在markerSet初始化后转换
_markerInfos = markerSet.map((marker) {
  return {
    'position': marker.position,
    'title': marker.infoWindow.title,
  };
}).toList();
  1. 使用Stack将GoogleMap和自定义文本组件叠加:
Stack(
  children: [
    GoogleMap(
      onMapCreated: (controller) => _controller.complete(controller),
      markers: markerSet,
      initialCameraPosition: const CameraPosition(target: LatLng(37.7749, -122.4194), zoom: 12),
    ),
    // 遍历生成自定义InfoWindow
    ..._markerInfos.map((info) {
      return FutureBuilder<ScreenCoordinate>(
        future: _controller.future.then((controller) => controller.getScreenCoordinate(info['position'])),
        builder: (context, snapshot) {
          if (!snapshot.hasData) return const SizedBox();
          final coord = snapshot.data!;
          return Positioned(
            left: coord.x.toDouble(),
            top: coord.y.toDouble() - 30, // 调整偏移避免遮挡Marker
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(4),
                boxShadow: const [BoxShadow(color: Colors.black26, blurRadius: 2)],
              ),
              child: Text(info['title'] ?? '', style: const TextStyle(fontSize: 12)),
            ),
          );
        },
      );
    }),
  ],
)
  1. 补充处理地图移动时的位置更新:
    在GoogleMap组件中添加onCameraMove回调,触发自定义InfoWindow的位置刷新(可结合状态管理实现):
onCameraMove: (_) {
  // 触发状态更新,重新计算所有自定义InfoWindow的位置
  setState(() {});
},

补充说明

  • 如果使用方案1,onCameraIdle可作为备选触发时机,但需加判断避免地图每次停止移动都重复执行。
  • 自定义InfoWindow需处理地图缩放、移动时的位置同步,上述示例用FutureBuilder结合setState实现基础逻辑,复杂场景可使用Provider、Riverpod等状态管理工具优化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:47:22