Customize Bottom ETA Panel

Customize styling of the bottom ETA panel

This example shows:

  • How to customize the styling of the Navigation bottom ETA panel

    • navViewPrimaryText

    • navViewSecondaryText

    • navigationViewRouteOverviewDrawable

    • navViewRouteOverviewBackground

  • How to config custom navigation style using NavLauncherConfig.Builder

docs-image

For all code examples, refer to Navigation Code Examples

activity_custom_bottom_etapanel_style.xml view source

1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical"
6 android:padding="10dp">
7
8 <LinearLayout
9 android:layout_width="wrap_content"
10 android:orientation="vertical"
11 android:layout_height="wrap_content">
12 <Button
13 android:id="@+id/fetchRoute"
14 android:layout_width="wrap_content"
15 android:layout_height="wrap_content"
16 android:textSize="12sp"
17 android:text="@string/fetch_route"/>
18
19 <Button
20 android:id="@+id/startNav"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:textSize="12sp"
24 android:text="@string/start_navigation_with_custom_bottom_panel"/>
25 </LinearLayout>
26
27 <TextView
28 android:id="@+id/routeGeometry"
29 android:layout_width="wrap_content"
30 android:layout_height="wrap_content"
31 android:layout_marginTop="10dp"/>
32
33 <ProgressBar
34 android:id="@+id/progress"
35 android:visibility="gone"
36 android:layout_width="wrap_content"
37 android:layout_height="wrap_content"
38 android:layout_gravity="center"/>
39
40</LinearLayout>

themes.xml view source

By default, the SDK requires a light and a dark theme, so we need to create two new Styles with the name we prefer, we use Theme.CustomNavBottomETAPanel and Theme.CustomNavBottomETAPanelDark in this case, and specify the parent as NavigationViewLight and NavigationViewDark respectively.

1<style name="Theme.CustomNavBottomETAPanel" parent="NavigationViewLight">
2 <!-- You can customize your navigation style here-->
3 <item name="navViewPrimaryText">#FFFF0115</item>
4 <item name="navViewSecondaryText">#FF1A6620</item>
5 <item name="navigationViewRouteOverviewDrawable">@drawable/ic_baseline_navigation_24</item>
6 <item name="navViewRouteOverviewBackground">#FF41FF00</item>
7</style>
8
9<style name="Theme.CustomNavBottomETAPanelDark" parent="NavigationViewDark">
10 <!-- You can customize your navigation style here-->
11 <item name="navViewPrimaryText">#FFFF0115</item>
12 <item name="navViewSecondaryText">#FF1A6620</item>
13 <item name="navigationViewRouteOverviewDrawable">@drawable/ic_baseline_navigation_24</item>
14 <item name="navViewRouteOverviewBackground">#FF41FF00</item>
15</style>

CustomBottomETAPanelStyleActivity view source

1package ai.nextbillion.navigation.demo.activity;
2
3import android.os.Bundle;
4import android.view.View;
5import android.widget.Button;
6import android.widget.ProgressBar;
7import android.widget.TextView;
8
9import ai.nextbillion.kits.directions.models.DirectionsResponse;
10import ai.nextbillion.kits.directions.models.DirectionsRoute;
11import ai.nextbillion.kits.geojson.Point;
12import ai.nextbillion.maps.location.modes.RenderMode;
13import ai.nextbillion.navigation.demo.R;
14import ai.nextbillion.navigation.ui.NBNavigation;
15import ai.nextbillion.navigation.ui.NavLauncherConfig;
16import ai.nextbillion.navigation.ui.NavigationLauncher;
17import androidx.annotation.NonNull;
18import androidx.appcompat.app.AppCompatActivity;
19import retrofit2.Call;
20import retrofit2.Callback;
21import retrofit2.Response;
22
23public class CustomBottomETAPanelStyleActivity extends AppCompatActivity implements View.OnClickListener {
24
25 private Button fetchRoute;
26 private Button startNav;
27 private TextView routeGeometry;
28 private DirectionsRoute directionsRoute;
29 private ProgressBar progress;
30 @Override
31 protected void onCreate(Bundle savedInstanceState) {
32 super.onCreate(savedInstanceState);
33 setContentView(R.layout.activity_custom_bottom_etapanel_style);
34 fetchRoute = findViewById(R.id.fetchRoute);
35 startNav = findViewById(R.id.startNav);
36 routeGeometry = findViewById(R.id.routeGeometry);
37 progress = findViewById(R.id.progress);
38 fetchRoute.setOnClickListener(this);
39 startNav.setOnClickListener(this);
40 startNav.setEnabled(false);
41
42 }
43
44 @Override
45 public void onClick(View view) {
46 if (view.getId() == R.id.fetchRoute) {
47 progress.setVisibility(View.VISIBLE);
48 Point origin = Point.fromLngLat(103.75986708439264, 1.312533169133601);
49 Point destination = Point.fromLngLat(103.77982271935586, 1.310473772283314);
50
51 NBNavigation.fetchRoute(origin, destination, new Callback<DirectionsResponse>() {
52 @Override
53 public void onResponse(@NonNull Call<DirectionsResponse> call, @NonNull Response<DirectionsResponse> response) {
54 progress.setVisibility(View.GONE);
55 //start navigation with the route we just fetched.
56 if (response.body() != null && !response.body().routes().isEmpty()) {
57 directionsRoute = response.body().routes().get(0);
58 routeGeometry.setText(String.format("Route Geometry: %s", directionsRoute.geometry()));
59 startNav.setEnabled(true);
60 }
61 }
62
63 @Override
64 public void onFailure(@NonNull Call<DirectionsResponse> call, @NonNull Throwable t) {
65 progress.setVisibility(View.GONE);
66 }
67 });
68 } else if (view.getId() == R.id.startNav) {
69 NavLauncherConfig.Builder configBuilder = NavLauncherConfig.builder(directionsRoute);
70 configBuilder.locationLayerRenderMode(RenderMode.GPS);
71 configBuilder.shouldSimulateRoute(true);
72 configBuilder.lightThemeResId(R.style.Theme_CustomNavBottomETAPanel);
73 configBuilder.darkThemeResId(R.style.Theme_CustomNavBottomETAPanelDark);
74 NavigationLauncher.startNavigation(CustomBottomETAPanelStyleActivity.this, configBuilder.build());
75 }
76 }
77}

Code Highlights

The key to customizing the panel is to modify the values in corresponding styles in theme.xml and then pass the style to NavLauncherConfig:

1NavLauncherConfig.Builder configBuilder = NavLauncherConfig.builder(directionsRoute);
2configBuilder.locationLayerRenderMode(RenderMode.GPS);
3configBuilder.shouldSimulateRoute(true);
4configBuilder.lightThemeResId(R.style.Theme_CustomNavBottomETAPanel);
5configBuilder.darkThemeResId(R.style.Theme_CustomNavBottomETAPanelDark);
6
7
8NavigationLauncher.startNavigation(CustomBottomETAPanelStyleActivity.this, configBuilder.build());

The key part of the code is the definition of the theme styles Theme_CustomNavBottomETAPanel based on NavigationViewLight and Theme_CustomNavBottomETAPanelDark based on NavigationViewDark These styles are used to customize the appearance of the navigation bottom ETA panel in the navigation view.

Code summary

Definition of Theme.CustomNavBottomETAPanel:

  • It is a custom style that extends the NavigationViewLight style. It allows customization of the navigation bottom ETA panel appearance.

  • The following items are defined within this style:

    • navViewPrimaryText: defines the color for the primary text in the navigation view. (e.g: the time remaining)

    • navViewSecondaryText: defines the color for the secondary text in the navigation view. (e.g: the distance remaining)

    • navigationViewRouteOverviewDrawable: sets the drawable resource for the route overview icon in the navigation view.

    • navViewRouteOverviewBackground: defines the background color for the route overview section in the navigation view.

The Theme.Theme_CustomNavBottomETAPanelDark style is similar to the previous style but is based on NavigationViewDark.

configBuilder.lightThemeResId(R.style.Theme_CustomNavBottomETAPanel) sets the light theme for the navigation UI, using the Theme_CustomNavBottomETAPanel style defined earlier. This style determines the appearance of the bottom ETA panel in the navigation view.

configBuilder.darkThemeResId(R.style.Theme_CustomNavBottomETAPanelDark) sets the dark theme for the navigation UI, using the Theme_CustomNavBottomETAPanelDark style defined earlier. This style is applied when the device's dark mode is enabled.

Besides, the action after clicking the fetch route button shows how to fetch a route using NBNavigation.fetchRoute(origin, destination, new Callback<DirectionsResponse>() { ... }); The origin and destination points are passed as parameters, along with a callback to handle the response asynchronously.