Navigation Theme Mode

Introduction

This example shows

  • Fetch routes using RouteRequestParams
  • Customize Navigation theme mode by setting themeMode in NavigationLauncherConfig
    • NavigationThemeMode.system: following system mode

    • NavigationThemeMode.light: Navigating in light mode

    • NavigationThemeMode.dark: Navigating in dark mode

      docs-imagedocs-image
      Android snapshotiOS snapshot

For all code examples, refer to Flutter Navigation Code Example

NavigationTheme view source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import 'package:flutter/material.dart';
import 'package:nb_maps_flutter/nb_maps_flutter.dart';
import 'package:nb_navigation_flutter/nb_navigation_flutter.dart';

class NavigationTheme extends StatefulWidget {
  static const String title = "Navigation Theme Mode";

  @override
  NavigationThemeState createState() => new NavigationThemeState();
}

class NavigationThemeState extends State<NavigationTheme> {
  NextbillionMapController? controller;
  List<DirectionsRoute> routes = [];
  late NavNextBillionMap navNextBillionMap;
  NavigationThemeMode themeMode = NavigationThemeMode.system;

  LatLng origin = LatLng( 1.312533169133601,  103.75986708439264);
  LatLng dest = LatLng( 1.310473772283314,  103.77982271935586);

  void _onMapCreated(NextbillionMapController controller) {
    this.controller = controller;
  }

  void _onStyleLoaded() {
    if (controller != null) {
      navNextBillionMap = NavNextBillionMap(controller!);
    }
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var screenHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      appBar: AppBar(
        title: const Text(NavigationTheme.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Container(
              constraints: BoxConstraints(maxHeight: screenHeight * 0.6),
              child: NBMap(
                onMapCreated: _onMapCreated,
                initialCameraPosition: CameraPosition(
                  target: LatLng(origin.latitude, 103.76986708439264),
                  zoom: 13.0,
                ),
                onStyleLoadedCallback: _onStyleLoaded,
              ),
            ),
            _buttonWidget(),
          ],
        ),
      ),
    );
  }

  void _fetchRoute() async {
    RouteRequestParams requestParams = RouteRequestParams(
      origin: origin,
      destination: dest,
      mode: ValidModes.car,
      geometryType: SupportedGeometry.polyline,
    );

    await NBNavigation.fetchRoute(requestParams, (routes, error) async {
      if (routes.isNotEmpty) {
        setState(() {
          this.routes = routes;
        });
        drawRoutes(routes);
      } else if (error != null) {
        print("====error====${error}");
      }
    });
  }

  void _startNavigation() {
    if (routes.isEmpty) return;
    NavigationLauncherConfig config = NavigationLauncherConfig(route: routes.first, routes: routes);
    config.locationLayerRenderMode = LocationLayerRenderMode.GPS;
    config.enableDissolvedRouteLine = false;
    config.shouldSimulateRoute = true;
    config.themeMode = themeMode;
    config.useCustomNavigationStyle = false;
    NBNavigation.startNavigation(config);
  }

  Future<void> drawRoutes(List<DirectionsRoute> routes) async {
    navNextBillionMap.clearRoute();
    await navNextBillionMap.drawRoute(routes);
  }

  @override
  void dispose() {
    super.dispose();
  }

  _buttonWidget() {
    return Padding(
      padding: const EdgeInsets.only(left: 8, top: 18.0),
      child: Column(
        children: [
          ElevatedButton(
            style: ButtonStyle(
              backgroundColor: MaterialStateProperty.all(Colors.blueAccent),
            ),
            onPressed: () {
              _fetchRoute();
            },
            child: const Text("Fetch Route"),
          ),
          ElevatedButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(routes.isEmpty ? Colors.grey : Colors.blueAccent),
                enableFeedback: routes.isNotEmpty),
            onPressed: () {
              themeMode = NavigationThemeMode.light;
              _startNavigation();
            },
            child: const Text("Start Navigation with light mode"),
          ),
          ElevatedButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(routes.isEmpty ? Colors.grey : Colors.blueAccent),
                enableFeedback: routes.isNotEmpty),
            onPressed: () {
              themeMode = NavigationThemeMode.dark;
              _startNavigation();
            },
            child: const Text("Start Navigation with dark mode"),
          ),
          ElevatedButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(routes.isEmpty ? Colors.grey : Colors.blueAccent),
                enableFeedback: routes.isNotEmpty),
            onPressed: () {
              themeMode = NavigationThemeMode.system;
              _startNavigation();
            },
            child: const Text("Start Navigation with following system mode"),
          ),
        ],
      ),
    );
  }

}

Code summary

The above code snippet defines a StatefulWidget named NavigationTheme, which demonstrates a simple navigation application using the NextbillionMap SDK for maps and the NBNavigation SDK for navigation features. The app allows users to fetch routes and start navigation with different theme modes (light, dark, or system default).

Initialization and Map Display:

The NBMap widget is used to display the map on the screen. The _onMapCreated method is called when the map is created and initializes the NextbillionMapController. The _onStyleLoaded method is called when the map style is loaded and creates a NavNextBillionMap instance using the NextbillionMapController.

Fetching Routes:

The _fetchRoute method is responsible for fetching routes between two coordinates (origin and dest) using the NBNavigation.fetchRoute function. The fetched routes are stored in the routes variable. The routes are drawn on the map using the drawRoutes method.

Starting Navigation:

The _startNavigation method is triggered when the user presses one of the navigation mode buttons. It creates a NavigationLauncherConfig object with the selected route and navigation settings. The navigation is started using the NBNavigation.startNavigation function with the specified config.

Explanation of Navigation Theme Mode Customization:

The navigation theme mode can be customized using the NavigationThemeMode enum. It has the following options:

  • NavigationThemeMode.light: Starts navigation with a light theme.
  • NavigationThemeMode.dark: Starts navigation with a dark theme.
  • NavigationThemeMode.system: Starts navigation with the system default theme.

When the user presses one of the navigation mode buttons, the _startNavigation method is called with the selected theme mode, and navigation is started accordingly.

The user presses the "Fetch Route" button to fetch the routes between the specified origin and destination coordinates.

After fetching the routes, the user can press one of the navigation mode buttons ("Start Navigation with light mode", "Start Navigation with dark mode", "Start Navigation with following system mode") to start navigation with the selected theme mode.