I ran into a bit of a wall when i tried to implement marker clustering in a Google Maps based app that i'm developing for work.
I figured i could use circles to represent clusters and swap markers for circles at a certain zoom threshold but that didn't work out, so now I'm using a clustering library.
The main issue is that said library doesn't take into account if the app uses a state management library, so here i am with an empty map once again.
I render my map like this:
class MapView extends StatelessWidget {
final LatLng initialLocation;
final Set<Marker> markers;
final CustomInfoWindowController infoWindowController;
final GoogleMapController? mapController;
final ClusterManager manager;
Completer<GoogleMapController> newMapController = Completer();
MapView(
{Key? key,
required this.initialLocation,
required this.markers,
required this.manager,
required this.infoWindowController,
this.mapController})
: super(key: key);
@override
Widget build(BuildContext context) {
final CameraPosition initialCameraPosition =
CameraPosition(target: initialLocation);
final renderSize = MediaQuery.of(context).size;
return SizedBox(
width: renderSize.width,
height: renderSize.height,
child: GoogleMap(
onTap: (position) {
infoWindowController.hideInfoWindow!();
if (context.read<MapBloc>().state.creatingLocation == true) {
context.read<MapBloc>().add(TurnCreationModeOff());
}
},
onCameraMove: (position) {
infoWindowController.onCameraMove!();
manager.onCameraMove(position);
},
onCameraIdle: () {
context.read<MapBloc>().add(HoldZoomLevel());
manager.updateMap();
context.read<MapBloc>().printMapID();
},
onLongPress: (LatLng location) {
context
.read<LocationCreationBloc>()
.add(LocationAcquired(location: location));
final Marker newMarker = Marker(
draggable: true,
markerId: const MarkerId('new'),
position: location,
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueViolet),
infoWindow: InfoWindow(
title: 'Pulsame para crear una nueva ubicacion',
snippet:
'Toca cualquier lado del mapa y reajusta el zoom para destruirme',
onTap: () {
Navigator.of(context).pushAndRemoveUntil(
CreationScreen.route(), (route) => false);
},
));
context.read<MapBloc>().add(RenderNewMarker(marker: newMarker));
},
initialCameraPosition: initialCameraPosition,
compassEnabled: true,
myLocationEnabled: true,
markers: markers,
zoomControlsEnabled: false,
myLocationButtonEnabled: true,
mapToolbarEnabled: false,
onMapCreated: (GoogleMapController controller) {
context.read<MapBloc>().add(MapInitialized(
controller: controller,
windowController: infoWindowController,
clusterManager: manager,
location:
context.read<LocationBloc>().state.lastKnownLocation));
newMapController.complete(controller);
manager.setMapId(controller.mapId);
infoWindowController.googleMapController = controller;
},
)
);
}
}
some stuff is heavily context dependant and i'd be happy to elaborate and provide more code samples if anyone needs them or has run into a similar issue.
i tried recoupling my business logic with my presentation layer, that being initializing a List of clusterable items and passing it to the Cluster Manager constructor but it crashed at runtime.