我已在 firestore 数据库中存储了项目的纬度和经度(字段为:item_latitude 和 item_longitude)。因此,所有项目都有纬度和经度。我可以使用流来获取项目,例如:
Stream<QuerySnapshot> getItems() async* {
yield* FirebaseFirestore.instance.collection("items").snapshots();
}
使用 StreamBuilder 或 FutureBuilder,我可以获得项目的单独属性,例如纬度和经度。 Geolocator 有一个计算距离的方法,这也是未来的方法:
double distance = await geolocator.distanceBetween(lat, long, lat1, long1);
我能够获取用户当前位置,在本例中为 lat1、long1(这是一条单独的记录)。问题是:Strem getItems 获取纬度和经度流,对于每个项目,我需要参考当前位置计算其当前距离。这意味着,当我迭代 GridView 中的项目时,我需要计算并显示距离。
我以抽象的方式写了这个问题,以便答案将解决如何基于同步数据流进行异步计算,这样当数据显示在页面的构建部分时,计算是在外部完成的,因为事实并非如此,构建不会接受同步计算的异步计算。
我的尝试导致了以下结果:第一次尝试:
child: StreamBuilder(
stream: FetchItems().getItems(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text("KE");
}
if (snapshot.hasData) {
DocumentSnapshot data = snapshot.data.docs[index];
double lat = data.data()[Str.ITEM_LATITUDE];
double long = data.data()[Str.ITEM_LATITUDE];
return
Text(getDistance(usersCurrentLocationLat,usersCurrentLocationLong,lat,long).toString());
//This fails and returns on the Text place holder the following: Instance of 'Future<dynamic>'
}
}),
我的第二次尝试如下:
child: StreamBuilder(
stream: FetchItems().getItems(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Text("KE");
}
if (snapshot.hasData) {
DocumentSnapshot data = snapshot.data.docs[index];
double lat = data.data()[Str.ITEM_LATITUDE];
double long = data.data()[Str.ITEM_LATITUDE];
double x = getDistance(usersCurrentLocationLat,usersCurrentLocationLong,lat,long);
return Text(x.toString());
//This fails and gives erro: type 'Future<dynamic>' is not a subtype of type 'double'
}
}),
进一步调查表明,以下用于获取当前位置并且也在 iniState 中引用的方法实际上确实获取了值(假设 Gps 已启用):
_getUserCurrentLocation() {
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best).then(
(Position position) {
setState(
() {
_currentPosition = position;
usersCurrentLocationLat = _currentPosition.latitude;
usersCurrentLocationLong = _currentPosition.longitude;
//a system print here returns current location as 0.3714267 32.6134379 (same for the
//StreamBuilder)
},
);
},
).catchError((e) {
print(e);
});
}
下面是计算距离的方法 - 使用提供的 Geolocator distanceBetween() 方法。
getDistance(double lat, double long, double lat1, double long1) async {
return distance = await geolocator.distanceBetween(lat, long, lat1, long1);
}
@override
void initState() {
super.initState();
_getUserCurrentLocation();
}
我如何能够迭代项目以获得其纬度和经度,计算距离并将其显示在文本上?这是一个一般性问题,非常欢迎可能的解决方案组合。请注意,在 StreamBuilder 中,我实际上能够使用以下内容打印以控制台每个坐标:
print("FROM CURRENT LOCATION HERE ----" + usersCurrentLocationLat.toString() +"::::::::" +
usersCurrentLocationLong.toString());
print("FROM STREAM FROM DB SURE ----" + lat.toString() +"::::::::" + long.toString());
它在控制台中打印数据库中的所有项目(一个示例):
I/flutter (30351): FROM CURRENT LOCATION HERE ----0.3732317::::::::32.6128083
I/flutter (30351): FROM STREAM FROM DB SURE ----2.12323::::::::2.12323
证明坐标确实得到了。
主要错误:“Future”类型不是“double”类型的子类型仍然存在,并且显示距离的文本被拉伸为红色。如果可以的话,请指导最佳方法 - 它也可能对将来的某人有所帮助。