I'm currently developing custom map widget, and struggling with updating map with new data.
I put my code of custom widget, but in summary, function flow will be
initState() => load data and start to draw markers
_loadMarkerIcons() => load icons bitmap before get markers(async)
_createMarkers() => get markers with my icons
_updateMarkers() => set state, start creating markers
build() => build map!
When I change data from page, it will just rebuild the widget. Since init will never called again, data will never changed. Usually in other projects(which I can code), I will call _loadMarkerIcons() directly from outside when data changed, but cannot find any solution like that in flutterflow.
Is there any way to solve this? ๐ฅฒ
class _MapSampleState extends State<MapSample> {
Completer<google_maps_flutter.GoogleMapController> _controller = Completer();
Map<String, google_maps_flutter.BitmapDescriptor> _customIcons = {};
Set<google_maps_flutter.Marker> _markers = {};
String imgurl = "asstspath";
google_maps_flutter.LatLng _center =
google_maps_flutter.LatLng(36.088110, -115.176468);
void _onMapCreated(google_maps_flutter.GoogleMapController controller) {
_controller.complete(controller);
}
@override
void initState() {
super.initState();
_loadMarkerIcons();
_center = google_maps_flutter.LatLng(widget.centerLat, widget.centerLng);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: google_maps_flutter.GoogleMap(
onMapCreated: _onMapCreated,
zoomGesturesEnabled: widget.allowZoom ?? false,
zoomControlsEnabled: widget.showZoomControls ?? false,
myLocationEnabled: widget.showLocation ?? false,
compassEnabled: widget.showCompass ?? false,
mapToolbarEnabled: widget.showMapToolbar ?? false,
trafficEnabled: widget.showTraffic ?? false,
initialCameraPosition: google_maps_flutter.CameraPosition(
target: _center,
zoom: 13.0,
),
markers: _markers,
),
);
}
Future<void> _loadMarkerIcons() async {
Set<String> uniqueIconPaths =
widget.mapData?.map((data) => data.icon).toSet() ??
{}; // Extract unique icon paths
for (String path in uniqueIconPaths) {
if (path.isNotEmpty) {
google_maps_flutter.BitmapDescriptor descriptor =
await google_maps_flutter.BitmapDescriptor.fromAssetImage(
ImageConfiguration(devicePixelRatio: 2.5),
"${imgurl}/${path}",
);
_customIcons[path] = descriptor;
}
}
_updateMarkers(); // Update markers once icons are loaded
}
void _updateMarkers() {
setState(() {
_markers = _createMarkers();
});
}
Set<google_maps_flutter.Marker> _createMarkers() {
var tmp = <google_maps_flutter.Marker>{};
widget.mapData?.forEach((mapData) {
final latlng.LatLng coordinates = mapData.latLng as latlng.LatLng;
final google_maps_flutter.LatLng googleMapsLatLng =
google_maps_flutter.LatLng(
coordinates.latitude, coordinates.longitude);
google_maps_flutter.BitmapDescriptor icon = _customIcons[mapData.icon] ??
google_maps_flutter.BitmapDescriptor.defaultMarker;
// Create and add the marker
final google_maps_flutter.Marker marker = google_maps_flutter.Marker(
markerId: google_maps_flutter.MarkerId(mapData.name),
position: googleMapsLatLng,
icon: icon,
infoWindow: google_maps_flutter.InfoWindow(title: mapData.name),
);
tmp.add(marker);
});
return tmp;
}
}