google-maps - Flutter - 使用 StreamBuilder 为谷歌地图提供实时更新
问题描述
我目前正在构建一个在谷歌地图上显示标记的应用程序。标记的位置是从 Firestore 数据库中提取的。目前,我正在成功检索和显示所有标记。但是,我需要根据数据库中的布尔值更新每个标记的图标。
这是我当前显示标记的方式。
我在主构建中创建地图:
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: mapToggle
? GoogleMap(
onMapCreated: onMapCreated,
compassEnabled: false,
polylines: route,
initialCameraPosition: CameraPosition(
target: LatLng(currentLocation.latitude,
currentLocation.longitude),
zoom: 12),
markers: markers,
)
: Center(
child: Text('Loading... Please wait...',
style: TextStyle(fontSize: 20.0)),
)),
然后我在 initState 中调用这个函数来获取我的标记:
chargePoints() {
_database.collection('charge_points').getDocuments().then((docs) {
if (docs.documents.isNotEmpty) {
for (int i = 0; i < docs.documents.length; i++) {
initMarker(docs.documents[i].data, docs.documents[i].documentID);
}
}
});
最后,initMarker 函数将每个标记添加到由 Google Map 实例获取的 Set 标记:
void initMarker(chargePoint, documentID) {
var markerIdVal = documentID;
final MarkerId markerId = MarkerId(markerIdVal);
// Creating a new Charge Point Marker
final Marker marker = Marker(
markerId: markerId,
icon: markerIcon,
position: LatLng(chargePoint['location'].latitude,
chargePoint['location'].longitude),
infoWindow: InfoWindow(
title: chargePoint['name'], snippet: chargePoint['type']),
onTap: () {
findBookings(context, chargePoint, documentID);
});
setState(() {
markers.add(marker);
});
所以我的问题是;当“占用”字段已更改时,如何将这些数据作为流返回,并提供一个更新相应标记图标的侦听器?
解决方案
好的,我有办法了!
我现在在主构建小部件中返回一个 StreamBuilder,它采用 Firestore 查询来返回所有标记的详细信息。
然后,我使用流提供的快照间歇性地转换上面 initMarker 函数中设置的所有标记的状态。
此外,标记集现在是一个地图。这对于访问标记以执行更新更有意义。
Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
标记使用它们的 MarkerId 进行管理,该标记与快照中返回的所有结果的 documentID 相关。
我不相信这个解决方案是完美的,但我希望我已经帮助了某人!
StreamBuilder<QuerySnapshot>(
stream: _servicesObj.getChargePoints(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Text('Loading Points');
}
snapshot.data.documents.forEach((change) {
var markerIdVal = change.documentID;
final MarkerId markerId = MarkerId(markerIdVal);
if (change.data['occupied'] == true) {
markers[markerId] = Marker(
markerId: markerId,
icon: pointOccupiedIcon,
position: LatLng(change.data['location'].latitude,
change.data['location'].longitude),
infoWindow: InfoWindow(
title: change.data['name'],
snippet: change.data['type']),
onTap: () {
findBookings(context, change.data, change.documentID);
});
} else {
markers[markerId] = Marker(
markerId: markerId,
icon: pointAvailableIcon,
position: LatLng(change.data['location'].latitude,
change.data['location'].longitude),
infoWindow: InfoWindow(
title: change.data['name'],
snippet: change.data['type']),
onTap: () {
findBookings(context, change.data, change.documentID);
});
}
});
推荐阅读
- android - Sqlite RecyclerView 没有附加适配器跳过布局
- java - 如何将字符串类型的 .txt 文件加载到 java 中的堆数据结构中?
- r - 如何在 R 中使用 tukeyTransform 存储 lambda 值?
- sql - 是否有可用于比较设置位数量的数据库/SQL 查询语法/函数
- azure - 如何使用 Azure PowerShell 将 VM 规模集与负载均衡器相关联
- xml - 如何防止在 Word XML 中插入拼写检查标签?
- python - Python程序读取文本文件后打印一个空行
- unity3d - 在 Unity 3D 中,控制台错误“.dll 未注册”是什么意思?
- reactjs - 为什么尝试在变量中渲染组件时会出错?
- php - 如何用标签包装所有文本节点?