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

