I have a statefull widget that uses a stream provider to show some markers which get updated in real time. I wan to be able to change the stream based on the center of the map, when a user moves the map camera. I have set up the following MultiProviders:
MultiProvider(providers: [
ChangeNotifierProvider(create: (context) => TabManager()),
FutureProvider<Position?>(
create: (_) => _geoLocatorSrv.getCurrentPosition(),
initialData: null),
ChangeNotifierProxyProvider<Position, GeoLocatorService>(
create: (_) => _geoLocatorSrv,
update: (ctx, position, geoLocator) {
return GeoLocatorService.fromCameraPosition(
CameraPosition(
target: LatLng(
position.latitude, position.longitude)));
}),
StreamProvider<List<ParkingSpot>>(
create: (_) => _db.getParkingSpots(
"parking-events/chirpstack/applications/1/devices", null),
initialData: const [],
),
ProxyProvider<GeoLocatorService, Stream<List<ParkingSpot>>>(
update: (_, geoLocatorService, parkingSpots) {
log("ProxyProvider GeolocationService updated");
return _db.getParkingSpots("collections");
}
)
]
My goal is to
- Get current location
- Upon location received create a GeoLocatorService (change notifier) with the value of the geo locator future
- Create a stream provider which "streams" collection data
- ProxyProvider which updates the stream based on changes in the GeoLocatorService changes in the camera position.
on my map statefull widget i have the following:
@override
Widget build(BuildContext context) {
var parkingSpots = Provider.of<List<ParkingSpot>>(context); # get the streamprovider with the items from the db
var currentPosition = Provider.of<Position?>(context); Get the current position
var geoLocatorNotifier = Provider.of<GeoLocatorService>(context); # get the notifier
CameraPosition? newCamPosition;
return Scaffold(
body: (currentPosition != null ) ? GoogleMap(
initialCameraPosition: _initialCameraPosition,
onMapCreated: (ctrl) {
_controller.complete(ctrl);
},
onCameraIdle: () {
if (newCamPosition != null){
geoLocatorNotifier.setCameraPosition(newCamPosition); //this is never called
}
},
onCameraMove: (position) {
setState(() {
newCamPosition = position;
});
},
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
) : const Center(child: CircularProgressIndicator()),
floatingActionButton: FloatingActionButton(
backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Colors.white,
onPressed: () async {
GoogleMapController ctrl = await _controller.future;
ctrl.animateCamera(
CameraUpdate.newCameraPosition(_initialCameraPosition));
},
child: const Icon(Icons.center_focus_strong)),
);
}
setCameraPosition in the GeoLocatorService is the following:
setCameraPosition(CameraPosition? position) {
cameraPosition = position;
notifyListeners();
}
But the stream never gets updated. Code in update callback in ProxyProvider<GeoLocatorService, Stream<List<ParkingSport>>>(). How can I have a StreamProvider update it's value based on a value of a ChangeNotifer?