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

flutter_map v8.1.1 地图间歇性不显示问题求助

问题描述

我正在使用flutter_map: ^8.1.1,代码实现如下:

return StreamBuilder<List<Marker>>(
    stream: carMarkerStream,
    builder: (context, snapshot) {
      return fm.FlutterMap(
        mapController: _fmController,
        options: fm.MapOptions(
            onMapEvent: (v) async {
              if (v.source == fm.MapEventSource.nonRotatedSizeChange &&
                  addressList.isEmpty) {
                _centerLocation =
                    LatLng(v.camera.center.latitude, v.camera.center.longitude);
                setState(() {});

                var val =
                    await geoCoding(_centerLocation.latitude, _centerLocation.longitude);
                if (val != '') {
                  setState(() {
                    if (addressList.where((element) => element.type == 'pickup').isNotEmpty) {
                      var add = addressList.firstWhere((element) => element.type == 'pickup');
                      add.address = val;
                      add.latlng = LatLng(_centerLocation.latitude, _centerLocation.longitude);
                    } else {
                      addressList.add(AddressList(id: '1', type: 'pickup', address: val, pickup: true, latlng: LatLng(_centerLocation.latitude, _centerLocation.longitude), name: userDetails['name'], number: userDetails['mobile']));
                    }
                  });

                  _lastCenter = _centerLocation;
                  ischanged = false;
                }
              }
              if (v.source ==
                  fm.MapEventSource.dragEnd) {
                _centerLocation =
                    LatLng(v.camera.center.latitude, v.camera.center.longitude);
                setState(() {});
                if (userDetails['enable_map_location_icon_drag_and_drop_feature'] ==
                    '0') {
                  var val = await geoCoding(_centerLocation.latitude, _centerLocation.longitude);
                  lowerLat = _centerLocation.latitude - (lat * 1.24);
                  lowerLon = _centerLocation.longitude - (lon * 1.24);
                  greaterLat = _centerLocation.latitude + (lat * 1.24);
                  greaterLon = _centerLocation.longitude + (lon * 1.24);
                  lower = geo.encode(lowerLon, lowerLat);
                  higher = geo.encode(greaterLon, greaterLat);

                  fdb = FirebaseDatabase.instance.ref('drivers').orderByChild('g').startAt(lower).endAt(higher);
                  if (val != '') {
                    setState(() {
                      if (addressList.where((element) => element.type == 'pickup').isNotEmpty) {
                        var add = addressList.firstWhere((element) => element.type == 'pickup');
                        add.address = val;
                        add.latlng = LatLng(_centerLocation.latitude, _centerLocation.longitude);
                      } else {
                        addressList.add(AddressList(id: '1', type: 'pickup', address: val, pickup: true, latlng: LatLng(_centerLocation.latitude, _centerLocation.longitude), name: userDetails['name'], number: userDetails['mobile']));
                      }
                    });

                    _lastCenter = _centerLocation;
                    ischanged = false;
                  }
                }
              }
            },
            onPositionChanged: (p, l) async {
              if (l == false) {
                if (addressList.isEmpty) {
                  _centerLocation = LatLng(p.center.latitude, p.center.longitude);
                  setState(() {});

                  var val = await geoCoding(_centerLocation.latitude, _centerLocation.longitude);
                  lowerLat = _centerLocation.latitude - (lat * 1.24);
                  if (val != '') {
                    setState(() {
                      if (addressList.where((element) => element.type == 'pickup').isNotEmpty) {
                        var add = addressList.firstWhere((element) => element.type == 'pickup');
                        add.address = val;
                        add.latlng = LatLng(_centerLocation.latitude, _centerLocation.longitude);
                      } else {
                        addressList.add(AddressList(id: '1', type: 'pickup', address: val, pickup: true, latlng: LatLng(_centerLocation.latitude, _centerLocation.longitude), name: userDetails['name'], number: userDetails['mobile']));
                      }
                    });

                    _lastCenter = _centerLocation;
                    ischanged = false;
                  }
                }
              }
            },
            initialCenter: fmlt.LatLng(center.latitude, center.longitude),
            initialZoom: 16,
            onTap: (P, L) {}),
        children: [
          fm.TileLayer(
            urlTemplate: (isDarkTheme == false)
                ? 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
                : 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
            userAgentPackageName: 'com.example.app',
          ),
          fm.MarkerLayer(
            markers: myMarkers
                .asMap()
                .map(
                  (k, value) => MapEntry(
                    k,
                    fm.Marker(
                      alignment: Alignment.topCenter,
                      point: fmlt.LatLng(myMarkers[k].position.latitude, myMarkers[k].position.longitude),
                      width: media.width * 0.7,
                      height: 50,
                      child: RotationTransition(
                        turns: AlwaysStoppedAnimation(myMarkers[k].rotation / 360),
                        child: Image.asset(
                          (myMarkers[k].markerId.toString().replaceAll('MarkerId(', '').replaceAll(')', '').split('#')[2].toString() == 'taxi')
                              ? 'assets/images/top-taxi.png'
                              : (myMarkers[k].markerId.toString().replaceAll('MarkerId(', '').replaceAll(')', '').split('#')[2].toString() == 'truck')
                                  ? 'assets/images/dev.png'
                                  : 'assets/images/bicy.png',
                        ),
                      ),
                    ),
                  ),
                )
                .values
                .toList(),
          ),
          const fm.RichAttributionWidget(
            attributions: [],
          ), 
        ],
      );
    });

但如下面截图所示,地图会隐藏。我尝试了各种方法,但问题仍未解决:

地图隐藏截图

需要说明的是,地图有时能正常显示,但偶尔会隐藏。

恳请您的帮助。

潜在解决方案
  • 避免在地图高频回调内直接调用setState:onMapEvent和onPositionChanged属于地图高频触发的回调函数,嵌套异步操作后调用setState会频繁触发组件重建,干扰地图渲染逻辑。建议将地理编码等异步逻辑移到独立方法中,或使用FutureBuilder处理结果,而非直接在回调内更新状态。

  • 完善StreamBuilder的状态处理:当前代码未处理snapshot的加载、错误状态,若carMarkerStream加载延迟或出现异常,可能导致地图渲染异常。添加状态判断:

    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return const Center(child: CircularProgressIndicator());
      }
      if (snapshot.hasError) {
        return const Center(child: Text('加载标记失败'));
      }
      // 现有地图代码
    }
    
  • 确保地图容器有明确尺寸约束:Flutter Map需要父组件提供明确的宽高限制,否则易出现渲染异常。检查地图所在父容器是否使用Expanded、Flexible或设置固定高度,保证地图能占据合理的可用空间。

  • 优化MarkerLayer的构建逻辑:当前对myMarkers的字符串解析和转换操作在每次组件重建时都会重复执行,易引发性能问题。建议提前预处理标记数据,将转换后的结果缓存,避免重复计算。

  • 升级flutter_map版本:8.1.1可能存在已知的渲染bug,尝试升级至最新稳定版,排查是否为版本迭代可修复的问题。

  • 优化地理编码操作:geoCoding异步操作若执行耗时过长,会阻塞UI线程间接影响地图渲染。可将该操作放到隔离线程中执行,或添加防抖处理,避免频繁触发请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:45:14