flutter_mapbox 1.0.0 copy "flutter_mapbox: ^1.0.0" to clipboard
flutter_mapbox: ^1.0.0 copied to clipboard

Add Turn By Turn Navigation to Your Flutter Application Using MapBox. Never leave your app when you need to navigate your users to a location.

flutter_mapbox #

pub.dev Platform License: MIT

Add turn-by-turn navigation to your Flutter app using the Mapbox Navigation SDK — without ever leaving your app.

Powered by Mapbox Navigation SDK v3 on both platforms — navigationcore 3.23.0 on Android, mapbox-navigation-ios 3.24+ (Swift Package Manager) on iOS.


Features #

  • Embedded map view with full turn-by-turn navigation
  • Full-screen navigation mode (edge-to-edge aware, with a location puck)
  • Alternative route selection (selectRoute)
  • Route geometry in the route_built event, for checking a route against your own data
  • Voice and banner instructions
  • Real-time route progress events
  • Vehicle dimension restrictions (height, width, weight)
  • Route avoidance (motorways, tolls, ferries, custom points)
  • Point of interest (POI) annotations with custom icons
  • Long-press to set destination
  • Free-drive / passive navigation mode
  • U-turn support at intermediate waypoints
  • Custom day/night map styles
  • Route simulation
  • Multi-language support

pub.dev #

https://pub.dev/packages/flutter_mapbox


Getting Started #

1. Add the dependency #

dependencies:
  flutter_mapbox: ^1.0.0

Requirements

Minimum
Flutter / Dart Flutter 3, Dart 3
Android compileSdk 36, Android Gradle Plugin 8.x, Java 17
iOS iOS 14, Swift Package Manager (see below)

Upgrading from 0.9.x: 1.0.0 moves both platforms to Mapbox Navigation SDK v3. See the changelog for what that changes in your app.

2. Mapbox Access Token #

You need a Mapbox account and a secret downloads token (with the DOWNLOADS:READ scope) to pull the native SDKs.

Android

Add your secret token to ~/.gradle/gradle.properties (or set it as a MAPBOX_DOWNLOADS_TOKEN environment variable):

MAPBOX_DOWNLOADS_TOKEN=sk.your_secret_token_here

⚠️ Keep secret (sk.) tokens out of your project's own gradle.properties and anything else under version control — they grant access to your Mapbox account. The user-level file above is outside every repository.

Add your public access token to android/app/src/main/res/values/strings.xml:

<string name="mapbox_access_token">pk.your_public_token_here</string>

iOS

Add your secret token to ~/.netrc:

machine api.mapbox.com
  login mapbox
  password sk.your_secret_token_here

Add your public access token to your Info.plist:

<key>MBXAccessToken</key>
<string>pk.your_public_token_here</string>

3. Platform configuration #

Android

Set the minimum SDK version in android/app/build.gradle:

android {
    defaultConfig {
        minSdkVersion 21
    }
}

Add location permissions to AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

The plugin's manifest also merges in FOREGROUND_SERVICE and FOREGROUND_SERVICE_LOCATION, which the v3 SDK needs for its trip session.

If your MainActivity hosts the embedded view, extend FlutterFragmentActivity rather than FlutterActivity.

iOS

The iOS side is built against Mapbox Navigation SDK v3, which is only distributed through Swift Package Manager, so your app must build plugins with SwiftPM:

flutter config --enable-swift-package-manager

CocoaPods-only builds are not supported from 1.0.0 (the Swift sources no longer compile against the v2 pods).

Set the minimum deployment target to iOS 14 (Xcode → Runner target → General → Minimum Deployments), and in your Podfile if you still have one:

platform :ios, '14.0'

Add location usage descriptions to Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location for navigation.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs your location for navigation.</string>

Usage #

Basic setup #

import 'package:flutter_mapbox/flutter_mapbox.dart';

Embedded navigation view #

MapBoxOptions options = MapBoxOptions(
  initialLatitude: 36.1175275,
  initialLongitude: -115.1839524,
  zoom: 13.0,
  tilt: 0.0,
  bearing: 0.0,
  enableRefresh: true,
  alternatives: true,
  voiceInstructionsEnabled: true,
  bannerInstructionsEnabled: true,
  allowsUTurnAtWayPoints: true,
  mode: MapBoxNavigationMode.drivingWithTraffic,
  units: VoiceUnits.imperial,
  simulateRoute: false,
  longPressDestinationEnabled: true,
  mapStyleUrlDay: "mapbox://styles/mapbox/navigation-day-v1",
  mapStyleUrlNight: "mapbox://styles/mapbox/navigation-night-v1",
  language: "en",
);

MapBoxNavigationView(
  options: options,
  onRouteEvent: _onRouteEvent,
  onCreated: (MapBoxNavigationViewController controller) async {
    _controller = controller;
    await _controller.initialize();
  },
);

Building a route #

final origin = WayPoint(
  id: "1",
  name: "Origin",
  latitude: 53.2110237,
  longitude: -2.8944236,
);
final destination = WayPoint(
  id: "2",
  name: "Destination",
  latitude: 53.701198,
  longitude: -2.461296,
);

await _controller.buildRoute(
  wayPoints: [origin, destination],
  options: options,
);

Starting navigation #

// Embedded (in-view) navigation
await _controller.startNavigation();

// Full-screen navigation
await _controller.startFullScreenNavigation();

Listening to route events #

Future<void> _onRouteEvent(RouteEvent e) async {
  switch (e.eventType) {
    case MapBoxEvent.route_built:
      // Route is ready
      break;
    case MapBoxEvent.navigation_running:
      // Navigation started
      break;
    case MapBoxEvent.progress_change:
      final progress = e.data as RouteProgressEvent;
      print(progress.currentStepInstruction);
      break;
    case MapBoxEvent.on_arrival:
      await _controller.finishNavigation();
      break;
    case MapBoxEvent.navigation_finished:
    case MapBoxEvent.navigation_cancelled:
      // Navigation ended
      break;
    default:
      break;
  }
}

Route data from route_built #

route_built carries one entry per route, primary first — the route length, duration and its line as [lng, lat] pairs. Use it to show alternatives or to check the route against your own data (e.g. low bridges).

case MapBoxEvent.route_built:
  // e.data is a JSON-encoded string of the JSON payload — decode twice.
  final routes = jsonDecode(jsonDecode(e.data as String) as String) as List;
  for (final r in routes) {
    final distance = r['distance'] as num;        // metres
    final duration = r['duration'] as num;        // seconds
    final coordinates = r['coordinates'] as List; // [[lng, lat], ...]
  }
  break;

Choosing an alternative route #

// Index into the route_built list; 0 is already the primary route.
await _controller.selectRoute(index: 1);

selectRoute fires route_built again with the chosen route moved to index 0.

Adding POI annotations #

await _controller.setPOI(
  groupName: "fuel",
  iconSize: 0.2,
  image: base64EncodedPngString,
  wayPoints: poiList,
);

// Remove POIs
await _controller.removePOI(groupName: "fuel");

Vehicle dimension restrictions #

options.maxHeight = "4.5"; // metres
options.maxWidth = "2.5";  // metres
options.maxWeight = "3.5"; // metric tons

Route avoidance #

MapBoxOptions(
  avoid: ["motorway", "toll", "ferry"],
  // ...
);

API Reference #

MapBoxOptions #

Property Type Description
initialLatitude double? Starting map latitude
initialLongitude double? Starting map longitude
zoom double? Initial zoom level (0–22)
bearing double? Camera bearing in degrees
tilt double? Camera tilt (0–60°)
language String? ISO 639-1 language code for instructions
mode MapBoxNavigationMode? Navigation mode (driving, cycling, walking)
units VoiceUnits? imperial or metric
alternatives bool? Show alternative routes
simulateRoute bool? Simulate driving the route
voiceInstructionsEnabled bool? Enable voice prompts
bannerInstructionsEnabled bool? Enable turn banners
allowsUTurnAtWayPoints bool? Allow U-turns at waypoints
longPressDestinationEnabled bool? Set destination via long press
enableFreeDriveMode bool? Passive/free-drive navigation
mapStyleUrlDay String? Mapbox style URL for day
mapStyleUrlNight String? Mapbox style URL for night
maxHeight String? Max vehicle height in metres
maxWidth String? Max vehicle width in metres
maxWeight String? Max vehicle weight in metric tons
avoid List<String>? Road types or points to avoid
padding EdgeInsets? Map view padding

MapBoxNavigationViewController #

Method / Property Description
initialize() Start listening for route events
buildRoute(wayPoints, options) Build a route between waypoints
startNavigation() Start embedded navigation
startFullScreenNavigation() Start full-screen navigation
finishNavigation() End the navigation session
clearRoute() Clear the current route
selectRoute(index) Make an alternative route the primary one
reCenterCamera() Re-center the map on the user
updateCameraPosition(lat, lng) Move the camera to a position
setPOI(groupName, image, iconSize, wayPoints) Add POI annotations
removePOI(groupName) Remove a group of POI annotations
distanceRemaining Remaining distance in metres
durationRemaining Remaining time in seconds
zoomLevel Current camera zoom level
centerCoordinates Current map center coordinates
selectedAnnotation Last tapped annotation ID

Contributing #

Contributions are welcome. Please open an issue or submit a pull request on GitHub.


License #

MIT — see LICENSE for details.

12
likes
140
points
785
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Add Turn By Turn Navigation to Your Flutter Application Using MapBox. Never leave your app when you need to navigate your users to a location.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_plugin_android_lifecycle, plugin_platform_interface

More

Packages that depend on flutter_mapbox

Packages that implement flutter_mapbox