nb_navigation_flutter 2.3.0+2 copy "nb_navigation_flutter: ^2.3.0+2" to clipboard
nb_navigation_flutter: ^2.3.0+2 copied to clipboard

A Flutter plugin for Nextbillion.ai Navigation SDK, providing turn-by-turn navigation.

Nextbillion Navigation Flutter #

codecov

Instroduction #

IMG_0378

Prerequisites #

  • Access Key
  • Android minSdkVersion 21+
  • iOS 12+
  • Flutter 3.22+

Initialization #

Add Dependency #

Add the following dependency to your project pubspec.yaml file to use the NB Navigation Flutter Plugin add the dependency to the pubspec.yaml (change the version to actual version that you want to use):

dependencies:
  nb_navigation_flutter: {version}
copied to clipboard

Configure the iOS and Android project #

iOS

  • In the build settings, locate "Build Libraries for Distribution" and ensure it is set to "No".

Android

  • Important :If you want to use the NavigationView, you need to to make the MainActivity extend FlutterFragmentActivity instead of FlutterActivity in the Android project.
    import io.flutter.embedding.android.FlutterFragmentActivity
      
    class MainActivity: FlutterFragmentActivity() {
      
    }
    
    copied to clipboard

Import the Package and Initialize the SDK #

Import the navigation plugin in your code

import 'package:nb_navigation_flutter/nb_navigation_flutter.dart';
copied to clipboard

Configure the NB Maps Token at the beginning of your app:

import 'package:nb_navigation_flutter/nb_navigation_flutter.dart';

class _NavigationDemoState extends State<NavigationDemo> {
  @override
  void initState() {
    super.initState();
    NextBillion.initNextBillion(YOUR_ACCESS_KEY);
  }
}
copied to clipboard

Required Permissions #

You need to grant location permission in order to use the location component of the NB Navigation Flutter Plugin, declare the permission for both platforms:

Android

Add the following permissions to the manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/> 
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.INTERNET" />
copied to clipboard
Requesting Location Runtime Permissions (Foreground and Background) in Android 6.0 and Above

For Android 6.0 (API 23) and above, you need to dynamically request permissions. Below is how to request location permissions using the permission_handler , including foreground and background permissions:

import 'package:permission_handler/permission_handler.dart';

Future<void> checkAndRequestLocationPermissions() async {
  // Request foreground location permission
  PermissionStatus status = await Permission.location.request();
  
  if (status.isGranted) {
    // If foreground location permission is granted, further request background location permission
    // This permission is needed for Android 10 and above, if you need to continue updating navigation data when the app goes to the background
    PermissionStatus backgroundStatus = await Permission.locationAlways.request();

    if (!backgroundStatus.isGranted) {
      // If background location permission is denied, notify the user and exit
      print("Background location permission is required.");
      return;
    }
  } else {
    // If foreground location permission is denied, notify the user
    print("Foreground location permission is required.");
    return;
  }
}
copied to clipboard
Requesting Notification Runtime Permission in Android 13 and Above

For Android 13 (API 33) and above, you need to dynamically request notification permissions if you want to show notifications while the app is in the background:

Future<void> checkAndRequestNotificationPermission() async {
  // Check notification permission status
  PermissionStatus status = await Permission.notification.status;

  if (!status.isGranted) {
    // Request notification permission
    status = await Permission.notification.request();
    if (status.isGranted) {
      print("Notification permission granted.");
    } else {
      print("Notification permission denied.");
    }
  } else {
    print("Notification permission already granted.");
  }
}
copied to clipboard

iOS

Add the following to the Runner/Info.plist to explain why you need access to the location data:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>  
  <string>[Your explanation here]</string>
<key>NSLocationWhenInUseUsageDescription</key>  
  <string>[Your explanation here]</string> 
copied to clipboard

Usage #

NB Maps #

If you need to use Maps related functions, for example: Display a Map widget, please refer to NB Flutter Maps Plugin

Observe and Tracking User Location #

  • Add the callback onUserLocationUpdated(UserLocation location)
  • Animate camera to user location within onStyleLoadedCallback
void _onMapCreated(NextbillionMapController controller) {
    this.controller = controller;
  }

_onUserLocationUpdate(UserLocation location) {
    currentLocation = location;
  }

_onStyleLoadedCallback() {
    if (currentLocation != null) {
      controller?.animateCamera(CameraUpdate.newLatLngZoom(currentLocation!.position, 14), duration: Duration(milliseconds: 400));
    }
  }

NBMap(
     onMapCreated: _onMapCreated,
     onStyleLoadedCallback: _onStyleLoadedCallback,
     initialCameraPosition: const CameraPosition(
            target: LatLng(0, 0),
            zoom: 14.0,
          ),
     trackCameraPosition: true,
     myLocationEnabled: true,
     myLocationTrackingMode: MyLocationTrackingMode.Tracking,
     onUserLocationUpdated: _onUserLocationUpdate,
)
copied to clipboard

Fetch Routes #

You can request routes with RouteRequestParams using NBNavigation, for the supported params, please refer to Navigation API

  • Create RouteRequestParams
RouteRequestParams requestParams = RouteRequestParams(
      origin: origin,
      destination: dest,
      // waypoints: [waypoint1, waypoint2],
      // language: 'en',
      // alternatives: true,
      // overview: ValidOverview.simplified,
      // avoid: [SupportedAvoid.toll, SupportedAvoid.ferry],
      // option: SupportedOption.flexible,
      // unit: SupportedUnits.imperial,
      // mode: ValidModes.car,
      // geometry: SupportedGeometry.polyline,
    );
copied to clipboard
  • Fetch routes Fetch route with requestParams using NBNavigation.fetchRoute(), and obtain the route result from Future<DirectionsRouteResponse>.

    DirectionsRouteResponse routeResponse = await NBNavigation.fetchRoute(requestParams);
    
    copied to clipboard
  • Draw routes

    After getting the routes, you can draw routes on the map view using NavNextBillionMap, If you need to use Maps related functions, for example: Display a Map widget, please refer to NB Flutter Maps Plugin

    Create NavNextBillionMap with NextbillionMapController in NBMap widget’s onStyleLoadedCallback callback:

    void _onMapCreated(NextbillionMapController controller) {
        this.controller = controller;
    }
      
    void _onStyleLoaded() {
        if (controller != null) async {
          navNextBillionMap = await NavNextBillionMap.create(controller!);
        }
      }
    
    copied to clipboard
  • Draw routes

    navNextBillionMap.drawRoute(routes);
    
    copied to clipboard
  • Fit Map camera to route points

    void fitCameraToBounds(List<DirectionsRoute> routes) {
        List<LatLng> multiPoints = [];
        for (var route in routes) {
           var routePoints = decode(route.geometry ?? '', _getDecodePrecision(route.routeOptions));
           multiPoints.addAll(routePoints);
        }
        if (multiPoints.isNotEmpty) {
          var latLngBounds = LatLngBounds.fromMultiLatLng(multiPoints);
          controller?.animateCamera(CameraUpdate.newLatLngBounds(latLngBounds, top: 50, left: 50, right: 50, bottom: 50));
        }
      }
      
      int _getDecodePrecision(RouteRequestParams? routeOptions) {
        return routeOptions?.geometry == SupportedGeometry.polyline ? PRECISION : PRECISION_6;
      }
    
    copied to clipboard
  • Clear routes

     navNextBillionMap.clearRoute();
    
    copied to clipboard
  • Toggle Alternative route visibility

     navNextBillionMap.toggleAlternativeVisibilityWith(visible);
    
    copied to clipboard
  • Toggle RouteDurationSymbol visibility

     navNextBillionMap.toggleDurationSymbolVisibilityWith(visible);
    
    copied to clipboard

Start navigation #

We provide two ways to start navigation: NavigationLauncherConfig and NBNavigationView to launch the navigation UI.

Start navigation with NavigationLauncherConfig #

NavigationLauncherConfig is a configuration class that provides the necessary settings for launching the navigation UI. You can customize the navigation experience by setting the route, theme mode, and other options.

NavigationLauncherConfig({
    required this.route,
    required this.routes,
    this.themeMode = NavigationThemeMode.system,
    this.shouldSimulateRoute = false,
    this.enableDissolvedRouteLine = true,
    this.navigationMapStyleUrl = NbNavigationStyles.nbMapCustomMapLightStyle,
    this.useCustomNavigationStyle = false,
    this.locationLayerRenderMode = LocationLayerRenderMode.GPS,
    this.showArriveDialog = true,
  });
copied to clipboard

Parameters

  • route: The selected route for directions
  • routes: A list of available routes
  • themeMode: The theme mode for navigation UI, default value is system
    • system: following system mode
    • light
    • dark
  • locationLayerRenderMode: The rendering mode for the location layer, default value is LocationLayerRenderMode.GPS
  • shouldSimulateRoute: Whether to simulate the route during navigation, default value is false
  • enableDissolvedRouteLine: Whether to enable the dissolved route line during navigation, default value is true
  • navigationMapStyleUrl: The map style URL for navigation UI. If you don't have access to the TomTom map style, you need to set the value as NbNavigationStyles.nbMapCustomMapLightStyle or NbNavigationStyles.nbMapCustomMapDarkStyle.
  • useCustomNavigationStyle: Whether to use custom navigation style, default value is false
  • locationLayerRenderMode: The rendering mode for the location layer, default value is LocationLayerRenderMode.GPS
  • showArriveDialog: Whether to show the arrive dialog when arriving at the destination, default value is true, only available for NavigationLauncherConfig

Example Usage

NavigationLauncherConfig config = NavigationLauncherConfig(route: routes.first, routes: routes, shouldSimulateRoute: true);

NBNavigation.startNavigation(config);
copied to clipboard

Launch Embedded NavigationView #

NBNavigationView is a customizable navigation view widget designed to provide seamless navigation experiences in your Flutter application. It offers various configuration options to cater to different navigation requirements, such as theme modes, location layer render modes, and custom styles.

NBNavigationView constructor

const NBNavigationView({
  super.key,
  required this.navigationOptions,
  this.onNavigationViewReady,
  this.onProgressChange,
  this.onNavigationCancelling,
  this.onArriveAtWaypoint,
  this.onRerouteFromLocation,
});
copied to clipboard

Parameters

By utilizing the NavigationLauncherConfig class, you can customize the navigation experience to meet your specific needs, from theme settings to location layer modes and custom styles.

  • navigationOptions (required): This parameter provides the necessary configuration for the navigation view.
  • onNavigationViewReady: A callback that is triggered when the navigation view is ready.
  • onProgressChange: A callback that is triggered when there is a change in the navigation progress.
  • onNavigationCancelling: A callback that is triggered when navigation is being canceled.
  • onArriveAtWaypoint: A callback that is triggered when arriving at a waypoint.
  • onRerouteFromLocation: A callback that is triggered when rerouting from a specific location.

Example Usage #

NBNavigationView(
  navigationOptions: NavigationLauncherConfig(
    route: selectedRoute,
    routes: allRoutes,
    themeMode: NavigationThemeMode.system,
  ),
  onNavigationViewReady: (controller) {
    // Handle navigation view ready
  },
  onProgressChange: (progress) {
    // Handle progress change
  },
  onNavigationCancelling: () {
    // Handle navigation canceling
  },
  onArriveAtWaypoint: (waypoint) {
    // Handle arriving at waypoint
  },
  onRerouteFromLocation: (location) {
    // Handle rerouting from location
  },
);
copied to clipboard

UI Components #

You can customize the styles of Navigation View

Android #

Add Custom style named CustomNavigationViewLight in your android project styles.xml with parent = "NavigationViewLight"

<style name="CustomNavigationViewLight" parent="NavigationViewLight">
//customize your navigation style
<item name="navViewBannerBackground">@color/color</item>
<item name="navViewBannerPrimaryText">@color/color</item>
...
</style>


<style name="CustomNavigationViewDark" parent="NavigationViewDark">
<item name="navViewBannerBackground">@color/colorAccent</item>

</style>
copied to clipboard

iOS #

Import nb_navigation_flutter in the AppDelegate of your ios project, customize the Navigation View Style by extending DayStyle and NightStyle

import nb_navigation_flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        customStyle()
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
     func customStyle() {
        NavStyleManager.customDayStyle = CustomDayStyle()
        NavStyleManager.customNightStyle = CustomNightStyle()
    }
}
copied to clipboard
import NbmapNavigation

class CustomDayStyle: DayStyle {
    required init() {
        super.init()
    }
    
    override func apply() {
        super.apply()
        ArrivalTimeLabel.appearance().font = UIFont.systemFont(ofSize: 18, weight: .medium).adjustedFont
        ArrivalTimeLabel.appearance().normalTextColor = #color
        BottomBannerContentView.appearance().backgroundColor = #color
    }
}

class CustomNightStyle: NightStyle {
    required init() {
        super.init()
    }
    
    override func apply() {
        super.apply()
        NavigationMapView.appearance().trafficUnknownColor = UIColor.green
    }
}
copied to clipboard

Running the example code #

Please refer to the RUN_EXAMPLE_CODE.md

4
likes
160
points
582
downloads

Publisher

verified publishernextbillion.ai

Weekly Downloads

2024.09.14 - 2025.03.29

A Flutter plugin for Nextbillion.ai Navigation SDK, providing turn-by-turn navigation.

Homepage
Repository (GitHub)

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter, nb_maps_flutter, plugin_platform_interface

More

Packages that depend on nb_navigation_flutter