Flutter Firestore使用orderBy后地图标记与折线仍乱序问题
问题分析与解决方案
我看了你的代码,发现几个关键问题导致标记和折线顺序不对,甚至显示异常:
核心问题点
- Marker ID重复:你每次循环都用同一个
MarkerId('addr'),这会导致新添加的Marker直接覆盖旧的,最终地图上只会显示最后一个Marker,看起来顺序完全错乱。 - Polyline重复添加:每次循环都往
_polylines里加一条新的Polyline,而且points用的是不断累加的latlngList,这会生成多条重叠的折线(从第一个点到当前遍历的点),视觉上就会显得混乱。 - InfoWindow信息错误:
latlngList[0].toString()固定显示第一个点的坐标,不是当前Marker对应的位置,这也是一个小问题。
修正后的代码
final Set<Polyline> _polylines = {}; List<LatLng> latlngList = []; static var today = DateTime.now(); String Daily = DateFormat('yyyy-MM-dd').format(today); void getLocation() async { // 先清空旧数据,避免重复显示 setState(() { _markers.clear(); _polylines.clear(); latlngList.clear(); }); final locationSnapshot = await _firestore .collection('$Daily') .orderBy('time', descending: false) .getDocuments(); // 第一步:遍历数据,收集坐标并添加每个Marker(用唯一ID) for (int index = 0; index < locationSnapshot.documents.length; index++) { var doc = locationSnapshot.documents[index]; LatLng latLng = LatLng(doc.data['latittude'], doc.data['longitude']); latlngList.add(latLng); setState(() { _markers.add(Marker( // 用文档ID或者索引作为唯一MarkerId,避免覆盖 markerId: MarkerId(doc.documentID), position: latLng, draggable: true, infoWindow: InfoWindow( // 显示当前Marker的坐标 title: latLng.toString(), snippet: '5 Star Rating', ), icon: BitmapDescriptor.defaultMarker, )); }); } // 第二步:所有点收集完成后,只添加一次Polyline if (latlngList.isNotEmpty) { setState(() { _polylines.add(Polyline( polylineId: const PolylineId('address'), color: Colors.blue, visible: true, width: 5, points: latlngList, )); }); } }
关键改进说明
- 清空旧数据:每次调用
getLocation前先清空标记、折线和坐标列表,确保新数据不会和旧数据混在一起。 - 唯一Marker ID:用文档的
documentID或者循环索引作为Marker的ID,保证每个Marker都是独立的,不会被覆盖。 - 延迟添加Polyline:等所有坐标都按顺序收集完成后,再一次性添加折线,这样折线会严格按照你从Firestore获取的排序顺序连接所有点。
- 修正InfoWindow内容:显示当前Marker对应的坐标,而不是固定的第一个点。
这样修改后,你的标记会按时间顺序全部显示出来,折线也会准确连接每个点的顺序啦!
内容的提问来源于stack exchange,提问作者Asbah Riyas
相关产品推荐
相关产品推荐

