Modèles d'intégration Mapbox Flutter
Modèles officiels pour intégrer le SDK Mapbox Maps pour Flutter (mapbox_maps_flutter) sur iOS et Android avec Dart.
Utilisez cette skill quand :
- Installer et configurer mapbox_maps_flutter dans une app Flutter
- Définir le token d'accès Mapbox correctement
- Initialiser un
MapWidgetavec les options caméra / style - Ajouter des annotations (points, cercles, lignes, polygones) et gérer les taps
- Afficher le puck de localisation de l'utilisateur
- Charger du GeoJSON depuis les assets de l'app
- Résoudre les échecs de build iOS après l'ajout de Mapbox
Ressources officielles :
Web et desktop ne sont pas supportés — le SDK Flutter cible iOS et Android uniquement.
Installation et configuration
Prérequis
- Flutter SDK 3.22.3 / Dart 3.4.4+
- iOS : cible de déploiement 14.0 ou supérieure
- Android : minSdk 21 ou supérieur
- Compte Mapbox gratuit
Étape 1 : Ajouter la dépendance
# pubspec.yaml
dependencies:
mapbox_maps_flutter: ^2.0.0
flutter pub get
Étape 2 : Relever la cible de déploiement iOS à 14.0 (requis)
C'est la cause la plus courante des échecs de build iOS après l'ajout de Mapbox. Le SDK Flutter nécessite iOS 14.0 et ne compilera pas avec la valeur par défaut de Flutter.
-
Ouvrez
ios/Runner.xcworkspacedans Xcode. -
Sélectionnez la cible Runner → General → définissez Minimum Deployments → iOS sur
14.0. -
Si
ios/Podfileexiste, mettez également à jour la ligne platform :# ios/Podfile platform :ios, '14.0'
Vous n'avez pas besoin de vous préoccuper de CocoaPods vs Swift Package Manager — mapbox_maps_flutter supporte les deux et Flutter choisit celui pour lequel votre app est configurée.
Étape 3 : Permission de localisation iOS
Ajoutez la chaîne de description à ios/Runner/Info.plist :
<key>NSLocationWhenInUseUsageDescription</key>
<string>Show your location on the map</string>
Étape 4 : Permissions Android
Ajoutez à android/app/src/main/AndroidManifest.xml :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Étape 5 : Configurer le token d'accès
Le modèle recommandé est de passer le token via --dart-define au moment du build/run et de le définir sur MapboxOptions avant de créer un MapWidget.
flutter run --dart-define=ACCESS_TOKEN=pk.your_token_here
// main.dart
import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
const accessToken = String.fromEnvironment('ACCESS_TOKEN');
void main() {
MapboxOptions.setAccessToken(accessToken);
runApp(const MaterialApp(home: MapScreen()));
}
Ne codez jamais les tokens en dur dans le code source. Pour la CI, passez --dart-define=ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN.
Initialisation de la map
Map basique
import 'package:flutter/material.dart';
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
class MapScreen extends StatelessWidget {
const MapScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: MapWidget(
key: const ValueKey('mapWidget'),
cameraOptions: CameraOptions(
center: Point(coordinates: Position(-122.4194, 37.7749)),
zoom: 12,
),
styleUri: MapboxStyles.STANDARD,
),
);
}
}
Récupérer le contrôleur MapboxMap
class MapScreen extends StatefulWidget {
const MapScreen({super.key});
@override
State<MapScreen> createState() => _MapScreenState();
}
class _MapScreenState extends State<MapScreen> {
MapboxMap? mapboxMap;
void _onMapCreated(MapboxMap controller) {
mapboxMap = controller;
}
@override
Widget build(BuildContext context) {
return MapWidget(
key: const ValueKey('mapWidget'),
onMapCreated: _onMapCreated,
cameraOptions: CameraOptions(
center: Point(coordinates: Position(-122.4194, 37.7749)),
zoom: 12,
),
);
}
}
Ajouter des annotations
Utilisez mapboxMap.annotations pour créer des gestionnaires pour les annotations de point, cercle, polyline et polygone. Les gestionnaires sont de longue durée — créez-les une fois et réutilisez-les pour les mises à jour.
Annotations de point avec une image personnalisée
import 'package:flutter/services.dart' show rootBundle;
PointAnnotationManager? pointAnnotationManager;
Future<void> _addMarkers(MapboxMap mapboxMap) async {
pointAnnotationManager = await mapboxMap.annotations.createPointAnnotationManager();
final bytes = await rootBundle.load('assets/marker.png');
final imageBytes = bytes.buffer.asUint8List();
final options = <PointAnnotationOptions>[
PointAnnotationOptions(
geometry: Point(coordinates: Position(-122.4194, 37.7749)),
image: imageBytes,
iconSize: 1.2,
),
PointAnnotationOptions(
geometry: Point(coordinates: Position(-122.4094, 37.7849)),
image: imageBytes,
),
];
await pointAnnotationManager!.createMulti(options);
}
N'oubliez pas de déclarer l'asset dans pubspec.yaml :
flutter:
assets:
- assets/marker.png
Gestion des taps
Utilisez manager.tapEvents — c'est l'API actuelle. addOnPointAnnotationClickListener est dépréciée.
tapEvents retourne un Cancelable que vous sauvegardez et sur lequel vous appelez .cancel() quand le listener n'est plus nécessaire :
final Cancelable tapSubscription = pointAnnotationManager!.tapEvents(
onTap: (annotation) {
debugPrint('Tapped annotation ${annotation.id}');
},
);
@override
void dispose() {
tapSubscription.cancel();
super.dispose();
}
Le même modèle — retournant un Cancelable — existe sur longPressEvents et dragEvents de chaque gestionnaire, et à travers les autres types d'annotations (CircleAnnotationManager.tapEvents, etc.).
Charger les annotations depuis GeoJSON
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
Future<void> _loadGeoJson(MapboxMap mapboxMap) async {
final raw = await rootBundle.loadString('assets/coffee_shops.geojson');
final geo = jsonDecode(raw) as Map<String, dynamic>;
final features = (geo['features'] as List).cast<Map<String, dynamic>>();
final manager = await mapboxMap.annotations.createPointAnnotationManager();
final icon = (await rootBundle.load('assets/coffee.png')).buffer.asUint8List();
final options = features.map((feature) {
final coords = feature['geometry']['coordinates'] as List;
return PointAnnotationOptions(
geometry: Point(coordinates: Position(coords[0] as double, coords[1] as double)),
image: icon,
);
}).toList();
await manager.createMulti(options);
}
Pour des milliers de features, utilisez plutôt une couche de style (GeoJsonSource + SymbolLayer) au lieu des annotations.
Afficher la localisation de l'utilisateur
Les permissions doivent déjà être accordées (utilisez permission_handler ou similaire) avant d'activer le puck.
await mapboxMap.location.updateSettings(LocationComponentSettings(
enabled: true,
puckBearingEnabled: true,
locationPuck: LocationPuck(
locationPuck2D: DefaultLocationPuck2D(),
),
));
Contrôle de la caméra
// Saut instantané
await mapboxMap.setCamera(CameraOptions(
center: Point(coordinates: Position(-80.1263, 25.7845)),
zoom: 14,
));
// Fly-to animé
await mapboxMap.flyTo(
CameraOptions(
center: Point(coordinates: Position(-80.1263, 25.7845)),
zoom: 17,
bearing: 180,
pitch: 30,
),
MapAnimationOptions(duration: 2000),
);
Dépannage
Le build iOS échoue avec « platform is lower than deployment target »
La cible de déploiement iOS par défaut de Flutter est inférieure au minimum de Mapbox (iOS 14). Définissez Minimum Deployments → iOS sur 14.0 sur la cible Runner dans Xcode. Si le projet a un ios/Podfile, définissez également platform :ios, '14.0' et réexécutez pod install.
setAccessToken n'a pas été appelée
Si vous oubliez d'appeler MapboxOptions.setAccessToken avant de créer un MapWidget, la map se chargera avec une grille vide. Appelez-le toujours dans main() avant runApp.
Le handler de tap d'annotation ne se déclenche pas
Assurez-vous que vous utilisez manager.tapEvents(onTap: ...) — addOnPointAnnotationClickListener est dépréciée. Confirmez également que le contrôleur MapboxMap est capturé via onMapCreated avant de créer le gestionnaire d'annotations.
Hot reload après un changement de permissions
iOS/Android ne relira pas les manifestes ou Info.plist sur hot reload. Redémarrez complètement l'app après modification des permissions.
Fichiers de référence
references/annotations.md— Modèles de cercle, polyline, polygone et recettes de source/couche GeoJSON.references/platform-setup.md— Configuration iOS/Android approfondie, stratégies de token, notes de signature de release.