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

Flutter 谷歌地图视图无法显示多个自定义标记图标如何解决

问题修复方案

你遇到的问题主要由以下几个错误导致,按优先级修复即可:

核心问题:所有Marker的ID重复

谷歌地图的Marker要求每个markerId必须全局唯一,且Set<Marker>会根据markerId自动去重,你所有标记都用了MarkerId('SomeId'),会导致添加的标记互相覆盖,最终Set里可能只剩1个不在视野范围内的标记,看起来就像全部不显示。

次要问题:异步操作未触发UI刷新

setCustomMarkers是异步方法,加载图标、添加标记完成后没有调用setState通知界面刷新,地图拿到的还是初始化时的空标记列表。

其他问题

  • 公交图标资源路径写错,你原来的代码里加载公交图标时用了train.png的路径
  • FutureBuilder每次重绘都会重复往_markers里添加旅游点标记,导致列表冗余

具体修复步骤

  1. 给所有Marker分配唯一ID,不管是自定义交通图标,还是旅游点标记,都用唯一标识作为markerId
  2. 异步加载完成后调用setState刷新界面
  3. 修复资源路径,避免重复添加标记

修复后的核心代码参考

// 修改setCustomMarkers方法
Future<void> setCustomMarkers() async {
  BitmapDescriptor portIcon, busIcon, trainIcon;

  final Uint8List markerIconPort = await getBytesFromAsset('assets/images/port.png', 100);
  final Uint8List markerIconTrain = await getBytesFromAsset('assets/images/train.png', 100);
  // 修复公交图标路径
  final Uint8List markerIconBus = await getBytesFromAsset('assets/images/bus.png', 100);

  portIcon = BitmapDescriptor.fromBytes(markerIconPort);
  trainIcon = BitmapDescriptor.fromBytes(markerIconTrain);
  busIcon = BitmapDescriptor.fromBytes(markerIconBus);

  // 给每个marker分配唯一ID
  _markers.add(Marker(
    markerId: MarkerId('port_1'),
    position: LatLng(40.672842, 14.769194),
    infoWindow: InfoWindow(title: "Port 1"),
    icon: portIcon,
  ));

  _markers.add(Marker(
    markerId: MarkerId('port_2'),
    position: LatLng(40.674126, 14.752421),
    infoWindow: InfoWindow(title: "Port 2"),
    icon: portIcon,
  ));

  _markers.add(Marker(
    markerId: MarkerId('train_1'),
    position: LatLng(40.675804, 14.772802),
    infoWindow: InfoWindow(title: "Train"),
    icon: trainIcon,
  ));

  _markers.add(Marker(
    markerId: MarkerId('bus_1'),
    position: LatLng(40.674102, 14.776989),
    infoWindow: InfoWindow(title: "Bus"),
    icon: busIcon,
  ));
  // 加载完成后刷新UI
  if(mounted) setState(() {});
}

// 修改FutureBuilder里的旅游点标记添加逻辑,避免重复添加,同时设置唯一ID
if (turisticPointList.isNotEmpty) {
  // 先移除旧的旅游点标记,避免重复添加
  _markers.removeWhere((marker) => marker.markerId.value.startsWith('turistic_'));
  for (int i = 0; i < turisticPointList.length; i++) {
    _markers.add(Marker(
      markerId: MarkerId('turistic_$i'),
      position: LatLng(
          double.parse(turisticPointList[i].latitudine),
          double.parse(turisticPointList[i].longitudine)),
      infoWindow: InfoWindow(
        title: AppLocalizations.of(context)
            .translate(turisticPointList[i].titolo),
      )));
  }
}

// iOS尺寸适配优化:getBytesFromAsset方法可以根据设备像素比动态调整尺寸
Future<Uint8List> getBytesFromAsset(String path, int width) async {
  // 适配iOS不同分辨率屏幕,按设备像素比缩放尺寸
  double pixelRatio = MediaQuery.of(context).devicePixelRatio;
  int targetWidth = (width * pixelRatio).round();
  ByteData data = await rootBundle.load(path);
  ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),
      targetWidth: targetWidth);
  ui.FrameInfo fi = await codec.getNextFrame();
  return (await fi.image.toByteData(format: ui.ImageByteFormat.png))
      .buffer
      .asUint8List();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:36:07