1

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.

0 Answers0