Route callouts
The Navigation SDK allows you to display callouts on a map that represent the duration of the route(s) and customize the style of the callouts. This is a common UI component used in turn-by-turn navigation applications.
Use the route callout UI component
The route callout UI component consists of two main classes:
- The
MapboxRouteCalloutApi
consumes the list ofNavigationRoute
objects and calculates callouts for these routes. - The
MapboxRouteCalloutView
class handles consuming the calculated callout data and rendering it on the map.
By default the route callout will be displayed as a bubble with an arrow attached to the route's geometry even if the route line is not rendered on the map. For the better UX experience set up the route line API following this guide
Instantiate the route callout API
Instantiate the MapboxRouteCalloutApi
and MapboxRouteCalloutView
classes in your Activity
or Fragment
.
val routeCallout = MapboxRouteCalloutApi()
val routeCalloutView = MapboxRouteCalloutView(mapView)
Draw route callouts by passing a list of NavigationRoute
instances to the MapboxRouteCalloutApi
and rendering the result with the MapboxRouteCalloutView
. Read more about requesting a NavigationRoute
in the Route generation guide.
A recommended way to draw route callouts is by registering a RoutesObserver
with MapboxNavigation
:
private val routesObserver = object : RoutesObserver {
override fun onRoutesChanged(result: RoutesUpdatedResult) {
/*
obtain metadata to enhance visualization of alternative routes
*/
val alternativesMetadata = mapboxNavigation.getAlternativeMetadataFor(
result.navigationRoutes
)
routeCallout.setNavigationRoutes(
result.navigationRoutes,
alternativesMetadata,
).apply { value ->
routeCalloutView.renderCallouts(value)
}
}
}
This approach ensures that whenever routes get updated the new information will be reflected on the map. This includes change in selected primary route, re-drawing callouts after a reroute event, refreshes to update duration, or removal callout of invalid alternatives after the fork is passed.
Be sure to always unregister observers in onStop()
or onDestroy()
.
Customize API behavior and appearance
Display the relative duration on callouts
By default, the API generates callouts for all provided routes and displays the total duration of each route, but in some cases like active navigation while the camera is following the puck it is worth showing callouts only for alternative routes and the related duration difference comparing with the primary one.
val routeCalloutOptions = MapboxRouteCalloutApiOptions.Builder()
.routeCalloutType(RouteCalloutType.RelativeDurationsOnAlternative)
.build()
routeCallout.updateOptions(routeCalloutOptions).apply { value ->
routeCalloutView.renderCallouts(value)
}
Adjust similar duration delta
When routeCalloutType
in the option MapboxRouteCalloutApiOptions
sets to RelativeDurationsOnAlternative
API may consider an alternative duration the same as the primary one (displaying "Similar ETA" label on callout).
The default value is 3 minutes, it means that any alternative route which duration more or less than 3 minutes comparing to primary one considered as a route with the ETA the same as the primary.
To adjust this threshold update the options as follow:
val routeCalloutOptions = MapboxRouteCalloutApiOptions.Builder()
.routeCalloutType(RouteCalloutType.RelativeDurationsOnAlternative)
.similarDurationDelta(1.minutes)
.build()
routeCallout.updateOptions(routeCalloutOptions).apply { value ->
routeCalloutView.renderCallouts(value)
}
Customize route callout appearance
There are the set of options that allows to change the appearance of route callout UI component.
To use different colors for callout UI component pass MapboxRouteCalloutViewOptions
to MapboxRouteCalloutView
through constructor:
val routeCalloutViewOptions = MapboxRouteCalloutViewOptions.Builder()
.backgroundColor(R.color.custom_background)
.selectedBackgroundColor(R.color.custom_selected_background)
.textColor(R.color.custom_text_color)
.selectedTextColor(R.color.custom_selected_text_color)
.build()
val routeCalloutView = MapboxRouteCalloutView(mapView, routeCalloutViewOptions)