我正在Flutter中构建一个基本应用程序,该应用程序可以获取用户的位置并以类似于Tinder的刷卡格式显示附近的地点。我设法实现了地理位置,但是在使用FutureProvider / Consumer时遇到一个奇怪的错误,即用户到该地点的相对距离被卡片组中的第一个距离值覆盖。尽管我不熟悉flutter和Provider程序包,但我相信对此有一个简单的解决方法。
附带说明: 在Google上搜索之后,我尝试使用FutureProvider.value()来防止旧值更新,但没有运气。
在此先感谢您的帮助或指导!
Command Line Task
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类确实导入了一个名为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);
}
}
答案 0 :(得分:1)
您必须向SwiperItem
添加一个具有唯一值(例如地点名称)的键,因为当前的颤抖认为该小部件保持不变,因此Consumer
的状态为最旧的最上面的小部件。
通过添加键,您可以告诉flutter您删除了最上面的窗口小部件,而新的最上面的窗口小部件实际上是第二个窗口小部件