Custom Map Style

This example shows how to Switch Runtime Map Style

  • Location Permissions Handling

  • Switch Map Style using nextbillionMap.setStyle(new Style.Builder().fromUri(styleUrl))

  • Tracking Current Location Automatically when MapReady

    • locationComponent.setLocationComponentEnabled(true);

    • locationComponent.setRenderMode(RenderMode.COMPASS);

    • locationComponent.setCameraMode(CameraMode.TRACKING);

Custom Map Style

For all code examples, refer to Android Maps SDK Code Examples

activity_location_layer_map_change.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
android:id="@+id/coordinator_layout"
5
android:layout_width="match_parent"
6
android:layout_height="match_parent"
7
android:orientation="vertical">
8
9
<ai.nextbillion.maps.core.MapView
10
android:id="@+id/mapView"
11
android:layout_width="match_parent"
12
android:layout_height="match_parent"
13
android:layout_marginBottom="0dp"
14
app:nbmap_uiAttribution="false" />
15
16
<com.google.android.material.floatingactionbutton.FloatingActionButton
17
android:id="@+id/fabStyles"
18
android:layout_width="wrap_content"
19
android:layout_height="wrap_content"
20
android:layout_gravity="end|bottom"
21
android:layout_marginBottom="16dp"
22
android:layout_marginEnd="16dp"
23
android:layout_marginRight="16dp"
24
android:src="@drawable/ic_layers"
25
android:tint="@android:color/white"
26
app:backgroundTint="@color/palette_mint_100"
27
app:layout_anchorGravity="top" />
28
29
</androidx.coordinatorlayout.widget.CoordinatorLayout>

CustomMapStyleActivity view source

1
package ai.nextbillion;
2
3
import android.annotation.SuppressLint;
4
import android.os.Bundle;
5
import android.widget.Toast;
6
7
import com.google.android.material.floatingactionbutton.FloatingActionButton;
8
9
import java.util.List;
10
11
import ai.nextbillion.maps.camera.CameraPosition;
12
import ai.nextbillion.maps.camera.CameraUpdateFactory;
13
import ai.nextbillion.maps.core.MapView;
14
import ai.nextbillion.maps.core.NextbillionMap;
15
import ai.nextbillion.maps.core.OnMapReadyCallback;
16
import ai.nextbillion.maps.core.Style;
17
import ai.nextbillion.maps.geometry.LatLng;
18
import ai.nextbillion.maps.location.LocationComponent;
19
import ai.nextbillion.maps.location.LocationComponentActivationOptions;
20
import ai.nextbillion.maps.location.LocationComponentOptions;
21
import ai.nextbillion.maps.location.modes.CameraMode;
22
import ai.nextbillion.maps.location.modes.RenderMode;
23
import ai.nextbillion.maps.location.permissions.PermissionsListener;
24
import ai.nextbillion.maps.location.permissions.PermissionsManager;
25
import androidx.annotation.NonNull;
26
import androidx.appcompat.app.AppCompatActivity;
27
28
public class CustomMapStyleActivity extends AppCompatActivity implements OnMapReadyCallback {
29
30
private MapView mapView;
31
private NextbillionMap nextbillionMap;
32
private PermissionsManager permissionsManager;
33
34
@Override
35
protected void onCreate(Bundle savedInstanceState) {
36
super.onCreate(savedInstanceState);
37
setContentView(R.layout.activity_location_layer_map_change);
38
39
mapView = findViewById(R.id.mapView);
40
FloatingActionButton stylesFab = findViewById(R.id.fabStyles);
41
42
stylesFab.setOnClickListener(v -> {
43
if (nextbillionMap != null) {
44
toggleMapStyle();
45
}
46
});
47
48
mapView.onCreate(savedInstanceState);
49
50
if (PermissionsManager.areLocationPermissionsGranted(this)) {
51
mapView.getMapAsync(this);
52
} else {
53
permissionsManager = new PermissionsManager(new PermissionsListener() {
54
@Override
55
public void onExplanationNeeded(List<String> permissionsToExplain) {
56
Toast.makeText(CustomMapStyleActivity.this, "You need to accept location permissions.",
57
Toast.LENGTH_SHORT).show();
58
}
59
60
@Override
61
public void onPermissionResult(boolean granted) {
62
if (granted) {
63
mapView.getMapAsync(CustomMapStyleActivity.this);
64
} else {
65
finish();
66
}
67
}
68
});
69
permissionsManager.requestLocationPermissions(this);
70
}
71
}
72
73
private void toggleMapStyle() {
74
nextbillionMap.getStyle(style -> {
75
String styleUrl = StyleConstants.DARK.equals(style.getUri()) ? StyleConstants.LIGHT : StyleConstants.DARK;
76
nextbillionMap.setStyle(new Style.Builder().fromUri(styleUrl));
77
});
78
}
79
80
@Override
81
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
82
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
83
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
84
}
85
86
@Override
87
public void onMapReady(@NonNull NextbillionMap nextbillionMap) {
88
this.nextbillionMap = nextbillionMap;
89
CameraPosition cameraPosition = new CameraPosition.Builder()
90
.target(new LatLng(22.70418008712976, 78.66264025041812))
91
.zoom(6)
92
.tilt(30)
93
.tilt(0)
94
.build();
95
nextbillionMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
96
nextbillionMap.setStyle(new Style.Builder().fromUri(StyleConstants.LIGHT),
97
style -> activateLocationComponent(style));
98
}
99
100
@SuppressLint("MissingPermission")
101
private void activateLocationComponent(@NonNull Style style) {
102
LocationComponent locationComponent = nextbillionMap.getLocationComponent();
103
104
locationComponent.activateLocationComponent(
105
LocationComponentActivationOptions
106
.builder(this, style)
107
.useDefaultLocationEngine(true)
108
.locationComponentOptions(LocationComponentOptions.builder(this)
109
.pulseEnabled(true)
110
.build())
111
.build());
112
113
locationComponent.setLocationComponentEnabled(true);
114
locationComponent.setRenderMode(RenderMode.COMPASS);
115
locationComponent.setCameraMode(CameraMode.TRACKING);
116
117
locationComponent.addOnLocationClickListener(
118
() -> Toast.makeText(this, "Location clicked", Toast.LENGTH_SHORT).show());
119
120
locationComponent.addOnLocationLongClickListener(
121
() -> Toast.makeText(this, "Location long clicked", Toast.LENGTH_SHORT).show());
122
}
123
124
@Override
125
protected void onStart() {
126
super.onStart();
127
mapView.onStart();
128
}
129
130
@Override
131
protected void onResume() {
132
super.onResume();
133
mapView.onResume();
134
}
135
136
@Override
137
protected void onPause() {
138
super.onPause();
139
mapView.onPause();
140
}
141
142
@Override
143
protected void onStop() {
144
super.onStop();
145
mapView.onStop();
146
}
147
148
@Override
149
protected void onSaveInstanceState(Bundle outState) {
150
super.onSaveInstanceState(outState);
151
mapView.onSaveInstanceState(outState);
152
}
153
154
@Override
155
protected void onDestroy() {
156
super.onDestroy();
157
mapView.onDestroy();
158
}
159
160
@Override
161
public void onLowMemory() {
162
super.onLowMemory();
163
mapView.onLowMemory();
164
}
165
}

This code is an Android application that demonstrates how to customize the map style and handle location permissions using the Nextbillion Maps SDK. Here's a summary of the code:

Initializing MapView:

  • The MapView is initialized by calling mapView.onCreate(savedInstanceState).

Location Permissions Handling:

  • The app checks if location permissions are granted using PermissionsManager.areLocationPermissionsGranted(this). If permissions are granted, the map is asynchronously loaded. Otherwise, the app requests location permissions using the PermissionsManager and handles the permission result in the onPermissionResult callback.

Switch Map Style:

  • The app provides a floating action button (FAB) to toggle the map style. When the FAB is clicked, the toggleMapStyle() method is called. It gets the current map style using nextbillionMap.getStyle() and switches between a dark and light style by setting the new style using
    • nextbillionMap.setStyle(new Style.Builder().fromUri(styleUrl)).

Tracking Current Location Automatically:

  • When the map is ready (onMapReady callback), the camera is positioned to a specific location and zoom level.

  • The map style is set to the light style, and the location component is activated using nextbillionMap.getLocationComponent().activateLocationComponent().

  • The location component is configured to use the default location engine and display a pulsing animation.

  • It is enabled and set to render mode COMPASS and camera mode TRACKING. The location component also listens for click and long-click events on the user's location.

    • locationComponent.setLocationComponentEnabled(true);
    • locationComponent.setRenderMode(RenderMode.COMPASS);
    • locationComponent.setCameraMode(CameraMode.TRACKING);

Additional lifecycle methods are implemented to manage the MapView, including onStart, onResume, onPause, onStop, onSaveInstanceState, onDestroy, and onLowMemory.

© 2024 NextBillion.ai all rights reserved.