Customize the NavNextbillionMap style at runtime

This example shows how to change the NavNextbillionMap style after the map is already loaded. In the following code example:

  • A list of the available map-style strings is provided in the code

  • A floating button is provided on the screen, each time user clicks on the button, the index will be changed and the map style will be updated accordingly

docs-image

For all code examples, refer to Navigation Code Examples

activity_custom_navigation_style.xml view source

1<?xml version="1.0" encoding="utf-8"?>
2<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 tools:context=".activity.CustomNavigationStyleActivity">
8
9 <ai.nextbillion.maps.core.MapView
10 android:id="@+id/mapView_customize_style"
11 android:layout_width="match_parent"
12 android:layout_height="match_parent"
13 app:nbmap_uiAttribution="false" />
14
15 <com.google.android.material.floatingactionbutton.FloatingActionButton
16 android:id="@+id/fab"
17 android:layout_width="wrap_content"
18 android:layout_height="wrap_content"
19 android:layout_gravity="end|bottom"
20 android:layout_margin="16dp"
21 app:srcCompat="@drawable/ic_simulation_restart"
22 tools:ignore="ContentDescription" />
23
24</androidx.coordinatorlayout.widget.CoordinatorLayout>

CustomNavigationStyleActivity view source

1package ai.nextbillion.navigation.demo.activity;
2
3import android.location.Location;
4import android.os.Bundle;
5
6import ai.nextbillion.kits.geojson.Point;
7import ai.nextbillion.maps.Nextbillion;
8import ai.nextbillion.maps.camera.CameraUpdate;
9import ai.nextbillion.maps.camera.CameraUpdateFactory;
10import ai.nextbillion.maps.core.MapView;
11import ai.nextbillion.maps.core.NextbillionMap;
12import ai.nextbillion.maps.core.OnMapReadyCallback;
13import ai.nextbillion.maps.core.Style;
14import ai.nextbillion.maps.geometry.LatLng;
15import ai.nextbillion.maps.location.modes.RenderMode;
16import ai.nextbillion.navigation.demo.R;
17import ai.nextbillion.navigation.ui.camera.CameraUpdateMode;
18import ai.nextbillion.navigation.ui.camera.NavigationCameraUpdate;
19import ai.nextbillion.navigation.ui.map.NavNextbillionMap;
20
21import androidx.annotation.NonNull;
22import androidx.annotation.Nullable;
23import androidx.appcompat.app.AppCompatActivity;
24
25import com.google.android.material.floatingactionbutton.FloatingActionButton;
26
27import java.util.ArrayList;
28
29/***
30 * This example shows how to change the map style of NavNextbillionMap dynamically
31 * You can also use style from other sources if available
32 */
33public class CustomNavigationStyleActivity extends AppCompatActivity implements OnMapReadyCallback {
34 private static final int CAMERA_ANIMATION_DURATION = 1000;
35 private static final int DEFAULT_CAMERA_ZOOM = 16;
36
37 private MapView mapView;
38 private FloatingActionButton floatingActionButton;
39 private NavNextbillionMap nbMap;
40 // a fake point in Singapore
41 private final Point fakePoint = Point.fromLngLat(103.852408, 1.276411);
42 private ArrayList<String> styleList = new ArrayList<>();
43 private int floatingButtonClickCount = 0;
44
45 @Override
46 protected void onCreate(@Nullable Bundle savedInstanceState) {
47 super.onCreate(savedInstanceState);
48 setContentView(R.layout.activity_custom_navigation_style);
49
50 setUpStyleList();
51 setUpFloatingActionButton();
52
53 mapView = findViewById(R.id.mapView_customize_style);
54 mapView.onCreate(savedInstanceState);
55 mapView.getMapAsync(this);
56 }
57
58 // a set of map styles provided by NextBillion.ai
59 private void setUpStyleList() {
60 styleList.add("https://api.nextbillion.io/maps/streets/style.json");
61 styleList.add("https://api.nextbillion.io/maps/hybrid/style.json");
62 styleList.add("https://api.nextbillion.io/maps/dark/style.json");
63 }
64
65 // here we use a counter to decide which map style should be set to the map
66 private void setUpFloatingActionButton() {
67 floatingActionButton = findViewById(R.id.fab);
68 floatingActionButton.setOnClickListener(view -> {
69 floatingButtonClickCount = (floatingButtonClickCount + 1) % styleList.size();
70 nbMap.retrieveMap().setStyle(new Style.Builder().fromUri(styleList.get(floatingButtonClickCount)));
71 });
72 }
73
74 @Override
75 public void onMapReady(@NonNull NextbillionMap nextbillionMap) {
76 nextbillionMap.setStyle(new Style.Builder().fromUri(styleList.get(floatingButtonClickCount)));
77 nextbillionMap.getStyle(style -> {
78 nbMap = new NavNextbillionMap(mapView, nextbillionMap);
79 nbMap.updateLocationLayerRenderMode(RenderMode.COMPASS);
80 animateCamera();
81 });
82 }
83
84 private void animateCamera() {
85 CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(fakePoint.latitude(), fakePoint.longitude()), DEFAULT_CAMERA_ZOOM);
86 NavigationCameraUpdate navigationCameraUpdate = new NavigationCameraUpdate(cameraUpdate);
87 navigationCameraUpdate.setMode(CameraUpdateMode.OVERRIDE);
88 nbMap.retrieveCamera().update(navigationCameraUpdate, CAMERA_ANIMATION_DURATION);
89 }
90
91 @Override
92 public void onStart() {
93 super.onStart();
94 mapView.onStart();
95 }
96
97 @Override
98 public void onResume() {
99 super.onResume();
100 mapView.onResume();
101 }
102
103 @Override
104 public void onLowMemory() {
105 super.onLowMemory();
106 mapView.onLowMemory();
107 }
108
109 @Override
110 public void onPause() {
111 super.onPause();
112 mapView.onPause();
113 }
114
115 @Override
116 public void onStop() {
117 super.onStop();
118 mapView.onStop();
119 }
120
121 @Override
122 protected void onDestroy() {
123 super.onDestroy();
124 mapView.onDestroy();
125 }
126}

Code Highlights

The key of update map style is MapView’s setStyle() method:

1nbMap.retrieveMap().setStyle(new Style.Builder().fromUri(styleList.get(floatingButtonClickCount)));

Code summary

This example provides an Android activity that shows how to change the style of a NavNextbillionMap after the map is already loaded. The activity has the following features:

  • A list of available map styles is provided in the code.

  • A floating button is provided on the screen. Each time the user clicks on the button, the index of the map style in the list is changed and the map style is updated accordingly.

The activity works as follows:

  • The activity creates a list of available map styles.

  • The activity creates a floating button and sets an onClick listener for the button.

  • The activity creates a NavNextbillionMap and sets the map style to the first style in the list.

  • The activity adds the NavNextbillionMap to the view hierarchy.

  • The activity sets the onClick listener for the floating button to a function that changes the map style.

The function (anonymous function inside floatingActionButton.setOnClickListener()) that changes the map style works as follows:

  • The function gets the current index of the map style in the list.

  • The function increments the current index by 1.

  • The function checks if the current index is greater than or equal to the length of the list.

  • If the current index is greater than or equal to the length of the list, the function sets the current index to 0.

  • The function gets the map style at the current index in the list.

  • The function sets the map style of the NavNextbillionMap to the map style that was retrieved.