gpt4 book ai didi

flutter - Flutter FutureProvider值未在Builder方法中更新

转载 作者:行者123 更新时间:2023-12-03 04:33:29 27 4
gpt4 key购买 nike

问题
我正在Flutter中构建一个基本应用程序,该应用程序可以获取用户的位置并以类似于Tinder的刷卡格式显示附近的地方。我设法实现了地理位置,但是在使用FutureProvider / Consumer时遇到一个奇怪的错误,即用户到该地点的相对距离被卡片组中的第一个距离值覆盖。尽管我不熟悉flutter和Provider软件包,但我相信对此有一个简单的解决方法。
旁注:在Google上搜索之后,我尝试使用FutureProvider.value()来防止旧值更新,但是没有运气。
预先感谢您的协助或指导!
快速演示
FutureProvider Bug Demo
所用包装
packages used
card_swipe.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(),
),
),
);
}
}
geolocator_service.dart
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);
}
}
Dart
快速说明: Place类确实导入了一个名为geometry.dart的自定义类,但这纯粹是为了构造Place对象,我敢肯定它不会影响该bug。因此,已将其省略。
import './geometry.dart';

class Place {
final String name;
final Geometry geometry;

Place(this.name, this.geometry);

Place.fromJson(Map<dynamic, dynamic> parsedJson)
: name = parsedJson['name'],
geometry = Geometry.fromJson(
parsedJson['geometry'],
);
}

最佳答案

您必须在SwiperItem中添加一个具有唯一值(例如地点名称)的键,因为当前的 flutter 认为该窗口小部件保持不变,因此Consumer获得了最旧的顶部窗口小部件的状态。
通过添加键,您可以告诉flutter您删除了最上面的窗口小部件,而新的最上面的窗口实际上是第二个窗口小部件

关于flutter - Flutter FutureProvider值未在Builder方法中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64530700/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com