Flutter - 每个ListView项运行异步函数

3

我有一个地点列表,我检索并在Listview Builder中显示。

每个位置都有纬度和经度值。

现在正在尝试使用GeoLocator插件(https://pub.dartlang.org/packages/geolocator)在Listview中包含“距离”字段 - 通过添加一个“查找最近”按钮获取用户位置,然后使用用户的lat/lon和每个位置的lat/lon计算距离。

由于“GeoLocator Calculate Distance Method”是异步的,因此无法直接将Geolocator().distanceBetween(userLat,userLon,storeLat,storeLon)插入小部件。

问题: 那么,当用户单击“查找最近”按钮时,如何使每个Listview项目通过getDistance方法并返回结果?

简化代码:

Future<List> getdata() async {
final response = await http.get(getStoreLocations);
return json.decode(response.body);
}


@override
Widget build(BuildContext context) {
return new Scaffold(
  appBar: new AppBar(title: new Text("Location"),),
  body: new FutureBuilder<List>(
    future: getdata(),
    builder: (context, snapshot) {
      if (snapshot.hasError) print(snapshot.error);
      return snapshot.hasData
          ? new BrowseStoreLocation(
          list: snapshot.data,)
          : new Center(
        child: new CircularProgressIndicator(),
      );
    },
  ),
);
}
}

GeoLocator 获取用户位置方法:

getLocation () async {
Position position = await Geolocator().getCurrentPosition(LocationAccuracy.best);
userLat = position.latitude;
userLon = position.longitude;
setState(() {

});
}

GeoLocator 计算距离方法:

getDistance()async {
double distanceInMeters = await Geolocator().distanceBetween(userLat, 
userLon, storeLat, storeLon);
distance = distanceInMeters/1000;
}

我尝试通过设置变量进行实验。打印显示了所有项目的storeLat和storeLon值,但只有最后一个listitem被计算并返回。

String storeLat = "";
String storeLon = "";
getDistance(storeLat,storeLon)async {
double distanceInMeters = await Geolocator().distanceBetween(userLat, userLon, double.parse(storeLat), double.parse(storeLon));
distance = distanceInMeters/1000;
setState(() {
});
}

new ListView.builder(
itemCount: widget.list == null ? 0 : widget.list.length,
itemBuilder: (context, i) {
storeLat = widget.list[i]['latitude'];
storeLon = widget.list[i]['longitude'];
print(storeLon+storeLat);
return Container(
child: Column(
children: <Widget>[
new Text(distance.toString())
],
),

嗨,达米恩,你找到解决方案了吗?我这几天也遇到了同样的问题...不知道如何使ListView项目等待查询。 - FilipeOS
对我来说,我只是让Listview Builder返回一个有状态的类,然后在其中使用Futurebuilder为每个Listview项运行异步函数。 - Damien Devillian
你能否发布那个答案吗?我会非常感激。 - FilipeOS
如果您找到了此问题的解决方案,能否在此处发布一下。谢谢。 - Upendra Siripurapu
通过这个链接的帮助,我成功解决了这个问题:https://stackoverflow.com/questions/60994455/flutter-looping-through-a-list-of-latitude-and-longitude-from-rest-api-to-get - yodeveloper
1个回答

1
你需要在ListView.builder中使用FutureBuilder,然后在其中调用getDistance方法。请注意保留HTML标签。
ListView.builder(
  itemCount: locationsList.length,
  itemBuilder: (context, position) {
    final current = locationsList[position];
    return FutureBuilder<String>(
      future: getDistance(current.latitude, current.longitude)
                   .then((location) => location.toString()),
      builder: (context, snapshot) {
        return Container(
          child: Column(
            children: <Widget>[new Text(snapshot.data)],
          ),
        );
     });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接