NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #1154 most downloaded on pub.dev
Official Mapbox Maps SDK for Flutter. Add an interactive map widget that renders Mapbox Vector Tile (MVT) maps. Customize it for Android, iOS, and Web.
Last release 3 days ago
05 Oct 2026
Ships on a steady schedule
a new release about every 1 weeks
Most releases are documented
notes for 36 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
4 years old
178 releases · first in 2022
> * PointAnnotation.iconImageCrossFade has been deprecated and setting a value to it will not have any impact. Use PointAnnotationManager.iconImageCro…
[!IMPORTANT] ⚠️ Breaking changes
- [Android] When a method returns
StylePropertyValuethe property values will now be typed rather than a string.PointAnnotation.iconImageCrossFadehas been deprecated and setting a value to it will not have any impact. UsePointAnnotationManager.iconImageCrossFadeinstead.- The STANDARD_EXPERIMENTAL style has been removed. Use the STANDARD style instead.
In this release we fixed a bug in our Android conversion code where the property values in StylePropertyValue were being returned as strings rather than their actual type. This fix will cause a behavioral change in the return value of the following methods on Android:
getStyleImportConfigProperties, getStyleImportConfigProperty, getStyleLayerProperty, getStyleSourceProperty, getStyleTerrainProperty, getStyleLightProperty.Expose new methods for working with style imports: addStyleImportFromJSON, addStyleImportFromURI, updateStyleImportWithJSON, updateStyleImportWithURI, and moveStyleImport.
Introduce dragEvents API to the Annotation Managers to handle drag event callbacks for annotations:
onBegin: Called when a drag gesture starts on an annotation.onChanged: Called continuously as the annotation is dragged.onEnd: Called once the drag gesture completes.Example usage:
manager.dragEvents(
onBegin: (annotation) {
print("Drag started for: ${annotation.id}");
},
onChanged: (annotation) {
print("Dragging at: ${annotation.geometry}");
},
onEnd: (annotation) {
print("Drag ended at: ${annotation.geometry}");
},
);
Promote interaction APIs to stable. The following APIs are now stable:
MapboxMap.addInteractionMapboxMap.removeInteractionMapboxMap.setFeatureStateForFeaturesetDescriptorMapboxMap.setFeatureStateForFeaturesetFeatureMapboxMap.getFeatureStateForFeaturesetDescriptorMapboxMap.getFeatureStateForFeaturesetFeatureMapboxMap.removeFeatureStateForFeaturesetDescriptorMapboxMap.removeFeatureStateForFeaturesetFeatureMapboxMap.resetFeatureStatesForFeaturesetMapboxMap.queryRenderedFeaturesForFeaturesetMove experimental modelElevationReference property to LocationPuck3D.
Fixed an issue where style expressions did not override constant values when both were present.
[ios] Fix crash when force unwrapping UIImage for point annotations.
Update MapboxMaps to v11.13.0
MapboxMap.startPerformanceStatisticsCollection / MapboxMap.stopPerformanceStatisticsCollection APIs allowing to start / stop collecting map rendering performance statistics.setCustomHttpHeader method to allow the plugin to modify HTTP headers dynamically.StandardBuildingState has been removed. Use StandardBuildingsState instead.top-image, bearing-image, and shadow-image properties on LocationIndicatorLayer are now paint properties instead of layout properties.onZoomListener to MapWidget to allowing listening to zoom events resulting from user gestures: pinching, double-tapping, or quick zooming. The event returns MapContentGestureContext, which includes touchPosition (the location of the gesture on the screen), point (the geographical coordinates of the gesture), and gestureState (the state of the gesture). See gestures_example.dart for implementation guidance.SymbolLayer.iconSizeScaleRange, SymbolLayer.iconSizeScaleRangeExpression, SymbolLayer.textSizeScaleRange, SymbolLayer.textSizeScaleRangeExpression, LineLayer.lineCrossSlope, LineLayer.lineElevationReference, LineLayer.lineWidthUnit, FillLayer.fillElevationReference.PointAnnotationManager.setIconSizeScaleRange(), PointAnnotationManager.getIconSizeScaleRange(), PointAnnotationManager.setTextSizeScaleRange(), PointAnnotationManager.getTextSizeScaleRange() , PolygonAnnotationManager.setFillElevationReference(), PolygonAnnotationManager.getFillElevationReference(), PolylineAnnotationManager.setLineCrossSlope(), PolylineAnnotationManager.getLineCrossSlope(), PolylineAnnotationManager.setLineElevationReference(), PolylineAnnotationManager.getLineElevationReference(), PolylineAnnotationManager.setLineWidthUnit(), PolylineAnnotationManager.getLineWidthUnit() as experimental.ClipLayer.clipLayerScope and ClipLayer.clipLayerTypes as stableBackgroundLayer.backgroundPitchAlignment as experimental[!IMPORTANT] The iOS minimum deployment target is now iOS 14.0.
Featureset, which allows Evolving Basemap styles, such as Standard, to export an abstract set of features, such as POI, buildings, and place labels, regardless of which layers they are rendered on. An Interaction can then be targeted to these features, modifying their state when interacted with. For example, you can add a TapInteraction to your map which targets the buildings Featureset. When a user taps on a building, the building will be highlighted and its color will change to blue.var tapInteraction = TapInteraction(StandardBuildings(),
(_, feature) {
mapboxMap.setFeatureStateForFeaturesetFeature(feature, StandardBuildingsState(highlight: true));
log("Building group: ${feature.group}");
});
mapboxMap.addInteraction(tapInteraction);
Specific changes:
MapboxMap.addInteraction method, which allows you to add interactions to the map.MapboxMap.removeInteraction method, which allows you to remove interactions from the map using an identifier mapboxMap.removeInteraction("tap_interaction_poi")TapInteraction and LongTapInteraction targeting the map itself.TapInteraction and LongTapInteraction, which allow you to add tap and longTap interactions to the map.FeaturesetDescriptor -- and convenience descriptors for StandardBuildings, StandardPOIs, and StandardPlaceLabels -- which allow you to describe the featureset you want Interactions to target.queryRenderedFeatures, querySourceFeatures, setFeatureState, getFeatureState, removeFeatureState, resetFeatureStateinteractive_features_example.dart.ClipLayer as stable.symbolElevationReference property on SymbolLayer.backgroundPitchAlignment property on BackgroundLayer.fillZOffset property on FillLayer.fillExtrusionBaseAlignment and fillExtrusionHeightAlignment properties on FillExtrusionLayer.ZOffset methods on PolygonAnnotationManager, PolylineAnnotationManager, and PointAnnotationManager as experimental.symbolElevationReference methods on PointAnnotationManager as experimental.PolylineAnnotationManager as experimental.emphasisCircleGlowRange to LocationIndicatorLayer to control the glow effect of the emphasis circle – from the solid start to the fully transparent end.ZOffset properties to PolylineAnnotationMessenger, PolygonAnnotationMessenger, and PointAnnotationMessenger.FillExtrusionBaseAlignment and FillExtrusionHeightAlignment, and BackgroundPitchAlignment enums.MapWidget. Control the camera’s initial position and behavior by specifying a ViewportState subclass in the viewport parameter. This allows for centering on specific locations, following the user’s position, or showing an overview of a geometry. If no viewport is provided, the map uses its default camera settings.MapWidget(
viewport: CameraViewportState(
center: Point(coordinates: Position(-117.918976, 33.812092)),
zoom: 15.0,
),
);
[!IMPORTANT] Configuring Mapbox's secret token is no longer required when installing our SDKs.
MapboxMap.styleGlyphURL. Use this property to apply custom fonts to the map at runtime, without modifying the base style.CameraChanged event. #704You can now observe the map's camera updates with onCameraChangeListener
onCameraChangeListener(CameraChangedEventData data) {
print("CameraChangedEventData: timestamp: ${data.timestamp}, cameraState: ${data.cameraState}");
}
MAPBOX_LOG_DEBUG with false value.Snapshotter. The crash could happen when creating/destroying multiple instances of Snapshotter in succession. #728ProxyBinaryMessenger, instead setup channel with a messageChannelSuffix. #715.RenderedQueryGeometry with typed constructors: RenderedQueryGeometry.fromList()/fromScreenBox()/fromScreenCoordinate().This change improves type safety and clarity in the code. By using specific constructors, you can ensure that the RenderedQueryGeometry is created with the correct type of data, reducing the risk of runtime errors and making the code easier to understand and maintain.
Example:
Before:
// Using the untyped default constructor
final geometry = RenderedQueryGeometry(type: Type.SCREEN_COORDINATE, value jsonEncode(screenCoordinate.encode()));
After:
// Using a typed constructor
final geometry = RenderedQueryGeometry.fromScreenCoordinate(screenCoordinate);
TileStore.You can now clear temporary map data from the data path defined in the given resource options, which is useful when you want reduce the disk usage or in case the disk cache contains invalid data.
await MapboxMapsOptions.clearData();
And you can now set additional options to a TileStore, for example, a maximum amount of bytes TileStore can use to store files., base URL to use for requests to the Mapbox API, or URL template for making tile requests.
// Set the disk quota to zero, so that tile regions are fully evicted
// when removed.
// This removes the tiles from the predictive cache.
tileStore.setDiskQuota(0);
Instead of setting a whole new GeoJSON object anew every time a single feature has changed, now you can apply more granular, partial GeoJSON updates.
If your features have associated identifiers - you can add, update, and remove them on individual basis in your GeoJSONSource. This is especially beneficial for GeoJSONSources hosting a large amount of features - in this case adding a feature can be up to 4x faster with the partial GeoJSON update API.
mapboxMap.style.addGeoJSONSourceFeatures(sourceId, dataId, features)
mapboxMap.style.updateGeoJSONSourceFeatures(sourceId, dataId, features)
mapboxMap.style.removeGeoJSONSourceFeatures(sourceId, dataId, featureIds)
StyleManager.getLayer() failing for ModelLayer, RasterParticleLayer and SlotLayer.In this case each even annotation will have random color, but others will use the global default specified in the annotation manager.
final circleAnnotationManager = await mapboxMap.annotations.createCircleAnnotationManager();
var annotations = <CircleAnnotationOptions>[];
for (var i = 0; i < 2000; i++){
var annotation = CircleAnnotationOptions(
geometry: createRandomPoint(),
circleColor: (i % 2 == 0) ? createRandomColor() : null,
);
annotations.add(annotation);
}
circleAnnotationManager.setCircleColor(Colors.blue.value);
autoMaxZoom property for GeoJsonSource to fix rendering issues with FillExtrusionLayer in some cases.ClipLayer to remove 3D data (fill extrusions, landmarks, trees) and symbols.SlotLayer.sourceId and SlotLayer.sourceLayer as they have no effect in this layer.SymbolLayer.symbolElevationReference and SymbolLayer.symbolZOffset.@experimental annotations to Layer's Expression properties.model-front-cutoff property from ModelLayer.lineTrimColor and lineTrimFadeRange on LineLayer which allow to set custom color for trimmed line and fade effect for trim.FillExtrusionLayer.fillExtrusionLineWidth that can switch fill extrusion rendering into wall rendering mode. Use this property to render the feature with the given width over the outlines of the geometry.MapboxMap.setSnapshotLegacyMode() to help avoiding MapboxMap.snapshot() native crash on some Samsung devices running Android 14. MapboxMap.setSnapshotLegacyMode() has no effect on iOS.GestureState to MapContentGestureContext to indicate whether gesture has been started, its touches have changed or it has ended.21.1.0MapboxStyles.STANDARD_SATELLITE style.MapDebugOptions is superseded by MapWidgetDebugOptions, expanding existing debug options with the new light, camera, and padding debug options in addition to the new Android-specific options: layers2DWireframe and layers3DWireframe.ModelLayer. To use a local assets, please specify it with asset:// scheme in the uri.mapboxMap.style.setStyleLayerProperty("layer", "line-gradient",
'["interpolate",["linear"],["line-progress"],0.0,["rgb",255,0,0],0.4,["rgb",0,255,0],1.0,["rgb",0,0,255]]');
After:
LineLayer(
...
lineGradientExpression: [
"interpolate",
["linear"],
["line-progress"],
0.0,
["rgb", 255, 0, 0],
0.4,
["rgb", 0, 255, 0],
1.0,
["rgb", 0, 0, 255]
],
);
text-occlusion-opacity, icon-occlusion-opacity, line-occlusion-opacity, model-front-cutoff, lineZOffset as experimental.clusterMinPoints property for GeoJSONSource.SlotLayer and RasterParticleLayer.LocationComponentSettings.slot.@experimental annotation to relevant APIs.LineJoin.NONE.text-occlusion-opacity, icon-occlusion-opacity, line-occlusion-opacity, model-front-cutoff, lineZOffset as experimental.clusterMinPoints property for GeoJSONSource.SlotLayer and RasterParticleLayer.LocationComponentSettings.slot.@experimental annotation to relevant APIs.mapboxMap.style.setStyleLayerProperty("layer", "line-gradient",
'["interpolate",["linear"],["line-progress"],0.0,["rgb",255,0,0],0.4,["rgb",0,255,0],1.0,["rgb",0,0,255]]');
After:
LineLayer(
...
lineGradientExpression: [
"interpolate",
["linear"],
["line-progress"],
0.0,
["rgb", 255, 0, 0],
0.4,
["rgb", 0, 255, 0],
1.0,
["rgb", 0, 0, 255]
],
);
You now have the convenience of directly initializing annotations with Turf's geometries, eliminating the need for converting geometry to JSON.
PointsGeographical positions denoted by Map<String?, Object?>? are migrated to Point type from turf package.
Pass Points directly instead of converting them to JSON.
Before:
CameraOptions(
center: Point(
coordinates: Position(
-0.11968,
51.50325,
)).toJson())
After:
CameraOptions(
center: Point(
coordinates: Position(
-0.11968,
51.50325,
)))
MapWidget's onTapListener/onLongTapListener/onScrollListener now receive MapContentGestureContext containing both touch position of the gesture, as well as the projected map coordinate corresponding to the touch position.
Before:
onTapListener: { (coordinate)
final lat = coordinate.x;
final lng = coordinate.y;
...
}
After:
onTapListener: { (context)
final coordinates = context.point.coordinates; // Position
final touchPosition = context.touchPosition; // ScreenCoordinate
...
}
Before:
PointAnnotationOptions(
geometry: Point(
coordinates: Position(0.381457, 6.687337)
).toJson()
)
PolygonAnnotationOptions(
geometry: Polygon(coordinates: [
[
Position(-3.363937, -10.733102),
Position(1.754703, -19.716317),
Position(-15.747196, -21.085074),
Position(-3.363937, -10.733102)
]
]).toJson()
)
PolylineAnnotationOptions(
geometry: LineString(coordinates: [
Position(1.0, 2.0),
Position(10.0, 20.0)
]).toJson()
)
After:
PointAnnotationOptions(
geometry: Point(
coordinates: Position(0.381457, 6.687337)
)
)
PolygonAnnotationOptions(
geometry: Polygon(coordinates: [
[
Position(-3.363937, -10.733102),
Position(1.754703, -19.716317),
Position(-15.747196, -21.085074),
Position(-3.363937, -10.733102)
]
])
)
PolylineAnnotationOptions(
geometry: LineString(coordinates: [
Position(1.0, 2.0),
Position(10.0, 20.0)
])
)
Show multiple maps at the same time with no performance penalty. With the all new Snapshotter you can get image snapshots of the map, styled the same way as MapWidget.
The Snapshotter class is highly configurable. You can set the final result at the time of construction using the MapSnapshotOptions. Once you've configured your snapshot, you can start the snapshotting process.
One of the key features of the Snapshotter class is the style object. This object can be manipulated to set different styles for your snapshot, as well as to apply runtime styling to the style, giving you the flexibility to create a snapshot that fits your needs.
final snapshotter = await Snapshotter.create(
options: MapSnapshotOptions(
size: Size(width: 400, height: 400),
pixelRatio: MediaQuery.of(context).devicePixelRatio),
onStyleLoadedListener: (_) {
// apply runtime styling
final layer = CircleLayer(id: "circle-layer", sourceId: "poi-source");
snapshotter?.style.addLayer(layer);
},
);
snapshotter.style.setStyleURI(MapboxStyles.STANDARD);
snapshotter.setCamera(CameraOptions(center: Point(...)));
...
final snapshotImage = await snapshotter.start()
Create snapshots of the map displayed in the MapWidget with MapboxMap.snapshot(). This new feature allows you to capture a static image of the current map view.
The snapshot() method captures the current state of the Mapbox map, including all visible layers, markers, and user interactions.
To use the snapshot() method, simply call it on your Mapbox map instance. The method will return a Future that resolves to the image of the current map view.
final snapshotImage = await mapboxMap.snapshot();
Please note that the snapshot() method works best if the Mapbox Map is fully loaded before capturing an image. If the map is not fully loaded, the method might return a blank image.
RasterArraySource, note that rasterLayers is a get-only property and cannot be set.TileCacheBudget, a property to set per-source cache budgets in either megabytes or tiles.iconColorSaturation, rasterArrayBand, rasterElevation, rasterEmissiveStrength, hillshadeEmissiveStrength, and fillExtrusionEmissiveStrength on their respective layers.MapboxMapsOptions.get/setWorldview() and MapboxMapsOptions.get/setLanguage() as experimental.onStyleImageMissingListener.cameraForCoordinates, please use cameraForCoordinatesPadding instead.DefaultLocationPuck2D. By passing an empty byte array, for example, the following code shows a puck 2D with custom top image, default bearing image and no shadow image.mapboxMap?.location.updateSettings(LocationComponentSettings(
enabled: true,
puckBearingEnabled: true,
locationPuck:
LocationPuck(locationPuck2D: DefaultLocationPuck2D(topImage: list, shadowImage: Uint8List.fromList([]))))
);
maps-lifecycle plugin crash with java.lang.IllegalStateException: Please ensure that the hosting activity/fragment is a valid LifecycleOwner.MapboxMapsOptions.get/setWorldview() and MapboxMapsOptions.get/setLanguage() as experimental.MapboxMapsOptions.get/setWorldview() and MapboxMapsOptions.get/setLanguage(). Use this to to adjust administrative boundaries/map language based on the map's audience.
Read more about Mapbox worldviews and language support.below parameter to createAnnotationManager(), use this to control the position of the annotation layer in relation to other style layers.DefaultLocationPuck2D type interchangeable with LocationPuck2D that allows customization of the default location indicator appearance._AnnotationManager.removeAnnotationManagerById() allowing to remove annotation manager by its id, without having to store a reference to the manager.MapboxMapsOptions.setBaseUrl(), MapboxMapsOptions.getDataPath(), MapboxMapsOptions.setDataPath(), MapboxMapsOptions.getAssetPath(), MapboxMapsOptions.setAssetPath(), MapboxMapsOptions.getTileStoreUsageMode() and MapboxMapsOptions.setTileStoreUsageMode() to static methods.padding parameter optional in MapboxMap.cameraForCoordinateBounds() and MapboxMap.cameraForCoordinates().MapWidget not being applied on Android.androidHostingMode constructor parameter to MapWidget. Use this to change the way platform MapView is being hosted by Flutter on Android. This changes the way map view is composited with Flutter UI, read more on this in Android Platform Views guide from the Flutter team.MapboxMap: isGestureInProgress(), isUserAnimationInProgress(), setConstrainMode(), setNorthOrientation(), setViewportMode() and reduceMemoryUse() are now available on iOS.LogConfiguration allowing to intercept logs produced by the plugin. Pass your custom LogWriterBackend to LogConfiguration.registerLogWriterBackend() to redirect logs produced by the mapping engine to your desired destination.MapWidget.onResourceRequestListener that can be used to subscribe to resource requests made by the map.MapWidget's onScroll event to be triggered whenever map is being panned instead of triggering it only after pan ends.LogConfiguration allowing to intercept logs produced by the plugin. Pass your custom LogWriterBackend to LogConfiguration.registerLogWriterBackend() to redirect logs produced by the mapping engine to your desired destination.MapWidget.onResourceRequestListener that can be used to subscribe to resource requests made by the map.MapWidget's onScroll event to be triggered whenever map is being panned instead of triggering it only after pan ends.androidHostingMode constructor parameter to MapWidget. Use this to change the way platform MapView is being hosted by Flutter on Android. This changes the way map view is composited with Flutter UI, read more on this in Android Platform Views guide from the Flutter team.MapboxMap: isGestureInProgress(), isUserAnimationInProgress(), setConstrainMode(), setNorthOrientation(), setViewportMode() and reduceMemoryUse() are now available on iOS.below parameter to createAnnotationManager(), use this to control the position of the annotation layer in relation to other style layers.DefaultLocationPuck2D type interchangeable with LocationPuck2D that allows customization of the default location indicator appearance._AnnotationManager.removeAnnotationManagerById() allowing to remove annotation manager by its id, without having to store a reference to the manager.MapboxMapsOptions.setBaseUrl(), MapboxMapsOptions.getDataPath(), MapboxMapsOptions.setDataPath(), MapboxMapsOptions.getAssetPath(), MapboxMapsOptions.setAssetPath(), MapboxMapsOptions.getTileStoreUsageMode() and MapboxMapsOptions.setTileStoreUsageMode() to static methods.padding parameter optional in MapboxMap.cameraForCoordinateBounds() and MapboxMap.cameraForCoordinates().MapWidget not being applied on Android.Bump platform Maps SDK dependencies to 11.0.0.
MapboxStyles.MAPBOX_STREETS (#248).package:turf/helpers.dart.style.getLayer when layer property is an Expression.pixelsForCoordinates implementation.style.localizeLabels.mapboxMap.attribution, mapboxMap.logo, mapboxMap.compass and mapboxMap.scaleBar settings.mapbox_maps_flutter due to naming conflict to be able publish to pub.dev.MapView to MapWidget.RenderCacheOptions.MapboxMap.cameraForCoordinates2 to MapboxMap.cameraForCoordinatesCameraOptions.styles.dart to mapbox_styles.dart.fill-extrusion_layer.dart to fill_extrusion_layer.dart,
location-indicator_layer.dart to location_indicator_layer.dart.MapboxMap.coordinatesForPixels._coordinateForPixel.MapWidget.onTapListener, MapWidget.onLongTapListener, MapWidget.onScrollListener.One column per quarter.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →