如何解决Flutter FutureProvider值未在Builder方法中更新
问题
我正在Flutter中构建一个基本应用程序,该应用程序可以获取用户的位置并以类似于Tinder的刷卡格式显示附近的地点。我设法实现了地理位置,但是在使用FutureProvider / Consumer时遇到一个奇怪的错误,即用户到该地点的相对距离被卡片组中的第一个距离值覆盖。尽管我不熟悉Flutter和Provider程序包,但我相信对此有一个简单的解决方法。
附带说明: 在Google上搜索之后,我尝试使用FutureProvider.value()来防止旧值更新,但没有运气。
在此先感谢您的帮助或指导!
快速演示
使用的包裹
card_swipe.dart
Command Line Task
geolocator_service.dart
import 'package:Flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:provider/provider.dart';
import 'package:swipe_stack/swipe_stack.dart';
import '../services/geolocator_service.dart';
import '../models/place.dart';
class CardSwipe extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _currentPosition = Provider.of<Position>(context);
final _placesProvider = Provider.of<Future<List<Place>>>(context);
final _geoService = GeoLocatorService();
return FutureProvider(
create: (context) => _placesProvider,child: Scaffold(
backgroundColor: Colors.grey[300],body: (_currentPosition != null)
? Consumer<List<Place>>(
builder: (_,places,__) {
return (places != null)
? Column(
children: [
SizedBox(height: 10.0),Container(
margin: EdgeInsets.only(top: 120.0),height: 600,child: Swipestack(
children: places.map((place) {
return SwiperItem(builder:
(SwiperPosition position,double progress) {
return FutureProvider(
create: (context) =>
_geoService.getdistance(
_currentPosition.latitude,_currentPosition.longitude,place.geometry.location.lat,place.geometry.location.lng),child: Consumer<double>(
builder: (_,distance,__) {
return (distance != null)
? Center(
child: Card(
child: Container(
height: 200,width: 200,child: Center(
child: Column(
mainAxisAlignment:
MainAxisAlignment
.center,children: [
Text(place.name),Text(
'${(distance / 1609).toStringAsFixed(3)} mi'),// convert meter to mi
],),)
: Container();
}),);
});
}).toList(),visibleCount: 3,stackFrom: StackFrom.Top,translationInterval: 6,scaleInterval: 0.03,onEnd: () => debugPrint("onEnd"),onSwipe: (int index,SwiperPosition position) =>
debugPrint("onSwipe $index $position"),onRewind:
(int index,SwiperPosition position) =>
debugPrint("onRewind $index $position"),],)
: Center(
child: CircularProgressIndicator(),);
},)
: Center(
child: CircularProgressIndicator(),);
}
}
place.dart
快速说明: Place类确实导入了一个名为geometry.dart的自定义类,但这纯粹是为了构造Place对象,我确定它不会影响错误。因此,已将其省略。
import 'package:geolocator/geolocator.dart';
class GeoLocatorService {
final geolocator = Geolocator();
Future<Position> getLocation() async {
return await geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,locationPermissionLevel: GeolocationPermission.location,);
}
Future<double> getdistance(
double startLat,double startLng,double endLat,double endLng) async {
return await geolocator.distanceBetween(startLat,startLng,endLat,endLng);
}
}
解决方法
您必须向SwiperItem
添加一个具有唯一值(例如地点名称)的键,因为当前的颤抖认为该小部件保持不变,因此Consumer
的状态为最旧的最上面的小部件。
通过添加键,您可以告诉flutter您删除了最上面的窗口小部件,而新的最上面的窗口小部件实际上是第二个窗口小部件
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。