这段代码使用Google Places API根据我的当前位置成功显示了附近的餐馆。但是,当我手动移动手机上的地图位置时,新的餐厅标记不会显示在地图的新位置上。下面是我的代码。我还评论了一些我试图做的事情,以更新标记到新的相机位置。我在谷歌地图中使用了oncamermove。任何基于新相机位置更新新餐厅标记的帮助都是非常感谢的。
import 'package:family_farms_forever/utilities/secrets.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_maps_webservice/places.dart';
import 'package:google_maps_flutter_platform_interface/src/types/marker_updates.dart';
void main() => runApp(const MyApp());
final places = GoogleMapsPlaces(apiKey: Secrets.iosApiKey);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Market Map",
home: Scaffold(
// We'll change the AppBar title later
appBar: AppBar(title: const Text("My Location")),
body: const MyMarketMap()),
);
}
}
class MyMarketMap extends StatefulWidget {
const MyMarketMap({super.key});
@override
State<StatefulWidget> createState() {
return _MyMarketMapState();
}
}
class _MyMarketMapState extends State<MyMarketMap> {
late Future<Position> _currentLocation;
late final Set<Marker> _markers = {};
@override
void initState() {
super.initState();
_currentLocation = Geolocator.getCurrentPosition();
}
Future<void> _retrieveNearbyRestaurants(LatLng userLocation) async {
PlacesSearchResponse response = await places.searchNearbyWithRadius(
Location(lat: userLocation.latitude, lng: userLocation.longitude),
10000,
type: "restaurant");
Set<Marker> restaurantMarkers = response.results
.map((result) => Marker(
markerId: MarkerId(result.name),
// Use an icon with different colors to differentiate between current location
// and the restaurants
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueAzure),
infoWindow: InfoWindow(
title: result.name,
snippet:
"Ratings: ${result.rating?.toString() ?? "Not Rated"}"),
position: LatLng(
result.geometry!.location.lat, result.geometry!.location.lng)))
.toSet();
setState(() {
_markers.addAll(restaurantMarkers);
});
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _currentLocation,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
// The user location returned from the snapshot
Position snapshotData = snapshot.data;
LatLng userLocation =
LatLng(snapshotData.latitude, snapshotData.longitude);
if (_markers.isEmpty) {
_retrieveNearbyRestaurants(userLocation);
}
// void upDateMarkers() {
// Set<Marker> updatedMarkers =
// {}; //new markers with updated position go here
// updatedMarkers = {};
// /// Then call the SetState function.
// /// I called the MarkersUpdate class inside the setState function.
// /// You can do it your way but remember to call the setState function so that the updated markers reflect on your Flutter app.
// /// Ps: I did not try the second way where the MarkerUpdate is called outside the setState buttechnically it should work.
// setState(() {
// MarkerUpdates.from(Set<Marker>.from(_markers),
// Set<Marker>.from(updatedMarkers));
// _markers = updatedMarkers;
// _markers.addAll(updatedMarkers);
// //swap of markers so that on next marker update the previous marker would be the one which you updated now.
// // And even on the next app startup, it takes the updated markers to show on the map.
// });
// }
return GoogleMap(
myLocationEnabled: true,
zoomGesturesEnabled: true,
//onCameraMove: (position) => upDateMarkers(),
initialCameraPosition: CameraPosition(
target: userLocation,
zoom: 12,
),
markers: _markers
..add(Marker(
markerId: const MarkerId("User Location"),
infoWindow: const InfoWindow(title: "User Location"),
position: userLocation)),
);
} else {
return const Center(child: Text("Failed to get user location."));
}
}
// While the connection is not in the done state yet
return const Center(child: CircularProgressIndicator());
});
}
}
你必须使用Stream来获取更新:
StreamBuilder<Position>(
stream: Geolocator.getPositionStream(
locationSettings: LocationSettings()
),
builder: (context, snapshot) {
... Do your Rest Coding Here...
你可以通过为[LocationSettings]参数指定[LocationSettings]类的实例来控制流的行为。标准设置是:LocationSettings。精度:允许通过提供(默认为"best")来控制位置更新的精度;LocationSettings。distanceFilter:允许控制设备在发出更新之前需要移动的最小距离(默认值为0,表示不使用过滤器);LocationSettings。timeLimit:允许设置超时时间。如果在两个抓取位置之间超过了超时间隔,将抛出[TimeoutException]。缺省情况下,未配置时间限制。