[英]Flutter - FutureBuilder works well on Android but not well on iOS
I implemented the FutureBuilder with the code below in order to get the distance from the user and the item that he wants buy but I get a weird result between Android and iOS .我用下面的代码实现了FutureBuilder以获得与用户的距离以及他想要购买的物品,但我在 Android 和 iOS 之间得到了一个奇怪的结果。
On Android works well and I get the distance for each item.在Android 上运行良好,我得到了每个项目的距离。 But on iOS I don't have the distance for each item and infact some item has the distance and some items get null value.
但是在iOS上,我没有每个项目的距离,实际上有些项目有距离,有些项目得到 null 值。
class ProductHorizontalListItem extends StatelessWidget {
const ProductHorizontalListItem({
Key? key,
required this.product,
required this.coreTagKey,
this.onTap,
}) : super(key: key);
final Product product;
final Function? onTap;
final String coreTagKey;
@override
Widget build(BuildContext context) {
final PsValueHolder valueHolder =
Provider.of<PsValueHolder>(context, listen: false);
Future<double> getCurrentLocation() async {
Position position = await Geolocator.getCurrentPosition();
double lat = position.latitude;
double long = position.longitude;
final double distanceInMeters = Geolocator.distanceBetween(
double.parse(position.latitude.toString()),
double.parse(position.longitude.toString()),
double.parse(product.itemLocation!.lat.toString()),
double.parse(product.itemLocation!.lng.toString()),
);
return Future.value(distanceInMeters);
}
return FutureBuilder<double>(
future: getCurrentLocation(),
builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
return InkWell(
onTap: onTap as void Function()?,
child: Container(
margin: const EdgeInsets.only(
left: PsDimens.space4, right: PsDimens.space4,
bottom: PsDimens.space12),
child: Text(
'${snapshot.data}',
textAlign: TextAlign.start,
style: Theme.of(context).textTheme.caption!.copyWith(
color: PsColors.textColor3
)))
);});
}
}
I also tried to handle the states of FutureBuilder in each way but nothing.我还尝试以各种方式处理 FutureBuilder 的状态,但没有。
iOS works bad, why? iOS 工作不正常,为什么?
I'm on Flutter 3.0.5 with Android Studio Chipmunk.我在 Flutter 3.0.5 和 Android Studio Chipmunk 上。
First, you should check the snapshot state before accessing its data.首先,您应该在访问其数据之前检查快照 state。 Otherwise you can get a null value, since the treatment has not been finished yet.
否则你可以得到一个 null 值,因为处理还没有完成。 Check
snapshot.connectionState
and snapshot.hasData
before accessing snapshot.data
.在访问
snapshot.data
之前检查snapshot.connectionState
和snapshot.hasData
。
Then, there is no need to convert latitudes and longitudes to String, then back to double.然后,无需将纬度和经度转换为String,然后再转换回double。
Eventually, you can replace the definition of final Function? onTap;
最终,您可以替换
final Function? onTap;
final Function? onTap;
by a VoidCallback
, to avoid parsing it in the Inkwell button.通过
VoidCallback
,以避免在 Inkwell 按钮中解析它。
Try this out:试试这个:
@override
Widget build(BuildContext context) {
Future<double> getCurrentLocation() async {
Position position = await Geolocator.getCurrentPosition();
final double distanceInMeters = Geolocator.distanceBetween(
position.latitude,
position.longitude,
product.itemLocation!.latitude,
product.itemLocation!.longitude,
);
return Future.value(distanceInMeters);
}
return FutureBuilder<double>(
future: getCurrentLocation(),
builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return InkWell(
onTap: onTap,
child: Container(
margin: const EdgeInsets.only(
left: PsDimens.space4,
right: PsDimens.space4,
bottom: PsDimens.space12,
),
child: Text(
'${snapshot.data}',
textAlign: TextAlign.start,
style: Theme.of(context).textTheme.caption!.copyWith(
color: PsColors.textColor3,
),
),
),
);
} else if (!snapshot.hasData) {
// Handle error case
return const Text('error');
} else {
// Display a loader or whatever to wait for the Future to complete
return const Center(child: CircularProgressIndicator());
}
},
);
}
I tried the code by replacing position and product.itemLocation by location of actual cities, and the distanceInMeters is correct.我通过实际城市的位置替换 position 和 product.itemLocation 来尝试代码,并且 distanceInMeters 是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.