Personalizzazione dell'interfaccia utente di navigazione
Puoi personalizzare elementi dell'interfaccia utente di navigazione e la mappa e
aggiungere indicatori personalizzati alla mappa. Consulta la pagina Norme per le linee guida sulle modifiche accettabili all'interfaccia utente di navigazione.
Visualizza il codice
< > Mostra/nascondi il codice Java per l'attività di navigazione.
package com.example.navsdkcustomization;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.google.android.libraries.navigation.Camera;
import com.google.android.libraries.navigation.LatLng;
import com.google.android.libraries.navigation.ListenableResultFuture;
import com.google.android.libraries.navigation.Marker;
import com.google.android.libraries.navigation.MarkerOptions;
import com.google.android.libraries.navigation.NavigationApi;
import com.google.android.libraries.navigation.NavigationFragment;
import com.google.android.libraries.navigation.NavigationMap;
import com.google.android.libraries.navigation.Navigator;
import com.google.android.libraries.navigation.SimulationOptions;
import com.google.android.libraries.navigation.StylingOptions;
import com.google.android.libraries.navigation.Waypoint;
/**
* An activity that displays a map and a customized navigation UI.
*/
public class NavigationActivityCustomization extends AppCompatActivity {
private static final String TAG = NavigationActivityCustomization.class.getSimpleName();
private Navigator mNavigator;
private NavigationFragment mNavFragment;
private NavigationMap mMap;
// Define the Sydney Opera House by specifying its place ID.
private static final String SYDNEY_OPERA_HOUSE = "ChIJ3S-JXmauEmsRUcIaWtf4MzE";
// Set fields for requesting location permission.
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private boolean mLocationPermissionGranted;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize the Navigation SDK.
initializeNavigationSdk();
}
/**
* Starts the Navigation SDK and sets the camera to follow the device's location.
* Calls the navigateToPlace() method when the navigator is ready.
*/
private void initializeNavigationSdk() {
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION },
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
if (!mLocationPermissionGranted) {
displayMessage("Error loading Navigation SDK: "
+ "The user has not granted location permission.");
return;
}
// Get a navigator.
NavigationApi.getNavigator(this, new NavigationApi.NavigatorListener() {
/**
* Sets up the navigation UI when the navigator is ready for use.
*/
@Override
public void onNavigatorReady(Navigator navigator) {
displayMessage("Navigator ready.");
mNavigator = navigator;
mNavFragment = (NavigationFragment) getFragmentManager()
.findFragmentById(R.id.navigation_fragment);
// Navigate to a place, specified by Place ID.
navigateToPlace(SYDNEY_OPERA_HOUSE);
}
/**
* Handles errors from the Navigation SDK.
* @param errorCode The error code returned by the navigator.
*/
@Override
public void onError(@NavigationApi.ErrorCode int errorCode) {
switch (errorCode) {
case NavigationApi.ErrorCode.NOT_AUTHORIZED:
displayMessage("Error loading Navigation SDK: Your API key is "
+ "invalid or not authorized to use the Navigation SDK.");
break;
case NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED:
displayMessage("Error loading Navigation SDK: User did not accept "
+ "the Navigation Terms of Use.");
break;
case NavigationApi.ErrorCode.NETWORK_ERROR:
displayMessage("Error loading Navigation SDK: Network error.");
break;
case NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING:
displayMessage("Error loading Navigation SDK: Location permission "
+ "is missing.");
break;
default:
displayMessage("Error loading Navigation SDK: " + errorCode);
}
}
});
}
/**
* Customizes the navigation UI and the map.
*/
private void customizeNavigationUI() {
// Set custom colors for the navigator.
mNavFragment.setStylingOptions(new StylingOptions()
.primaryDayModeThemeColor(0xff1A237E)
.secondaryDayModeThemeColor(0xff3F51B5)
.primaryNightModeThemeColor(0xff212121)
.secondaryNightModeThemeColor(0xff424242)
.headerLargeManeuverIconColor(0xffffff00)
.headerSmallManeuverIconColor(0xffffa500)
.headerNextStepTypefacePath("/system/fonts/NotoSerif-BoldItalic.ttf")
.headerNextStepTextColor(0xff00ff00)
.headerNextStepTextSize(20f)
.headerDistanceTypefacePath("/system/fonts/NotoSerif-Italic.ttf")
.headerDistanceValueTextColor(0xff00ff00)
.headerDistanceUnitsTextColor(0xff0000ff)
.headerDistanceValueTextSize(20f)
.headerDistanceUnitsTextSize(18f)
.headerInstructionsTypefacePath("/system/fonts/NotoSerif-BoldItalic.ttf")
.headerInstructionsTextColor(0xffffff00)
.headerInstructionsFirstRowTextSize(24f)
.headerInstructionsSecondRowTextSize(20f)
.headerGuidanceRecommendedLaneColor(0xffffa500));
// Get the map.
mMap = mNavFragment.getMap();
// Turn off the traffic layer on the map.
mMap.setTrafficEnabled(false);
// Place a marker at the final destination.
if (mNavigator.getCurrentRouteSegment() != null) {
LatLng destinationLatLng = mNavigator.getCurrentRouteSegment()
.getDestinationLatLng();
Bitmap destinationMarkerIcon = BitmapFactory.decodeResource(
getResources(), R.drawable.ic_person_pin_48dp);
mMap.addMarker(new MarkerOptions()
.position(destinationLatLng)
.icon(destinationMarkerIcon)
.title("Destination marker"));
// Listen for a tap on the marker.
mMap.setOnMarkerClickListener(new NavigationMap.OnMarkerClickListener() {
@Override
public void onMarkerClick(Marker marker) {
displayMessage("Marker tapped: "
+ marker.getTitle() + ", at location "
+ marker.getPosition().latitude + ", "
+ marker.getPosition().longitude);
}
});
}
// Set the camera to follow the device location with 'TILTED' driving view.
mNavFragment.getCamera().followMyLocation(Camera.Perspective.TILTED);
}
/**
* Requests directions from the user's current location to a specific place (provided
* by the Google Places API).
*/
private void navigateToPlace(String placeId) {
Waypoint destination;
try {
destination = Waypoint.fromPlaceId(placeId, null);
} catch (Waypoint.UnsupportedPlaceIdException e) {
displayMessage("Error starting navigation: Place ID is not supported.");
return;
}
// Create a future to await the result of the asynchronous navigator task.
ListenableResultFuture<Navigator.RouteStatus> pendingRoute =
mNavigator.setDestination(destination);
// Define the action to perform when the SDK has determined the route.
pendingRoute.setOnResultListener(
new ListenableResultFuture.OnResultListener<Navigator.RouteStatus>() {
@Override
public void onResult(Navigator.RouteStatus code) {
switch (code) {
case OK:
// Hide the toolbar to maximize the navigation UI.
if (getActionBar() != null) {
getActionBar().hide();
}
// Customize the navigation UI.
customizeNavigationUI();
// Enable voice audio guidance (through the device speaker).
mNavigator.setAudioGuidance(
Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE);
// Simulate vehicle progress along the route for demo/debug builds.
if (BuildConfig.DEBUG) {
mNavigator.getSimulator().simulateLocationsAlongExistingRoute(
new SimulationOptions().speedMultiplier(5));
}
// Start turn-by-turn guidance along the current route.
mNavigator.startGuidance();
break;
// Handle error conditions returned by the navigator.
case NO_ROUTE_FOUND:
displayMessage("Error starting navigation: No route found.");
break;
case NETWORK_ERROR:
displayMessage("Error starting navigation: Network error.");
break;
case ROUTE_CANCELED:
displayMessage("Error starting navigation: Route canceled.");
break;
default:
displayMessage("Error starting navigation: "
+ String.valueOf(code));
}
}
});
}
/**
* Handles the result of the request for location permissions.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is canceled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
}
/**
* Shows a message on screen and in the log. Used when something goes wrong.
* @param errorMessage The message to display.
*/
private void displayMessage(String errorMessage) {
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
Log.d(TAG, errorMessage);
}
}
Modalità giorno principale: il colore giorno dell'intestazione di navigazione
Modalità giorno secondaria: il colore diurno dell'indicatore della prossima svolta.
Modalità notturna principale: il colore notturno dell'intestazione di navigazione
Modalità notturna secondaria: il colore notturno dell'indicatore della prossima svolta.
Elementi di testo per le istruzioni
Colore testo
Carattere
Dimensioni del testo della prima riga
Dimensioni del testo della seconda riga
Elementi di testo per i passaggi successivi
Carattere
Colore del testo del valore della distanza
Dimensioni del testo del valore della distanza
Colore del testo delle unità di misura
Dimensioni del testo delle unità di distanza
Icone di manovra
Colore dell'icona della manovra grande
Colore dell'icona della piccola manovra
Indicazione delle corsie in cui posizionarsi
Colore della corsia o delle corsie consigliate
Nell'esempio seguente viene illustrato come impostare le opzioni di stile:
private NavigationFragment mNavFragment;
mNavFragment = (NavigationFragment) getFragmentManager()
.findFragmentById(R.id.navigation_fragment);
// Set the styling options on the fragment.
mNavFragment.setStylingOptions(new StylingOptions()
.primaryDayModeThemeColor(0xff1A237E)
.secondaryDayModeThemeColor(0xff3F51B5)
.primaryNightModeThemeColor(0xff212121)
.secondaryNightModeThemeColor(0xff424242)
.headerLargeManeuverIconColor(0xffffff00)
.headerSmallManeuverIconColor(0xffffa500)
.headerNextStepTypefacePath("/system/fonts/NotoSerif-BoldItalic.ttf")
.headerNextStepTextColor(0xff00ff00)
.headerNextStepTextSize(20f)
.headerDistanceTypefacePath("/system/fonts/NotoSerif-Italic.ttf")
.headerDistanceValueTextColor(0xff00ff00)
.headerDistanceUnitsTextColor(0xff0000ff)
.headerDistanceValueTextSize(20f)
.headerDistanceUnitsTextSize(18f)
.headerInstructionsTypefacePath("/system/fonts/NotoSerif-BoldItalic.ttf")
.headerInstructionsTextColor(0xffffff00)
.headerInstructionsFirstRowTextSize(24f)
.headerInstructionsSecondRowTextSize(20f)
.headerGuidanceRecommendedLaneColor(0xffffa500));
Disattivare il livello di traffico
Utilizza NavigationMap.setTrafficEnabled() per abilitare o disabilitare il livello del traffico sulla mappa. Questa impostazione influisce sulle indicazioni della
compattezza del traffico mostrate sulla mappa nel complesso, ma non sulle indicazioni
del traffico sul percorso tracciato dal navigatore.
private NavigationMap mMap;
// Get the map.
mMap = mNavFragment.getMap();
// Turn off the traffic layer on the map.
mMap.setTrafficEnabled(false);
Aggiungi indicatori personalizzati
Puoi aggiungere indicatori personalizzati alla mappa per indicare i punti d'interesse per l'applicazione o per gli utenti. Ad esempio, potresti voler indicare il punto di prelievo alla fine del percorso. Usa NavigationMap.addMarker() per aggiungere
un indicatore e NavigationMap.setOnMarkerClickListener()
per ascoltare i tocchi su un indicatore.
Il codice seguente utilizza un'icona archiviata nelle risorse disegnabili del progetto, R.drawable.ic_person_pin_48dp. Puoi
utilizzare qualsiasi immagine adatta alla tua app.
// Place a marker at the final destination.
if (mNavigator.getCurrentRouteSegment() != null) {
LatLng destinationLatLng = mNavigator.getCurrentRouteSegment()
.getDestinationLatLng();
Bitmap destinationMarkerIcon = BitmapFactory.decodeResource(
getResources(), R.drawable.ic_person_pin_48dp);
mMap.addMarker(new MarkerOptions()
.position(destinationLatLng)
.icon(destinationMarkerIcon)
.title("Destination marker"));
// Listen for a tap on the marker.
mMap.setOnMarkerClickListener(new NavigationMap.OnMarkerClickListener() {
@Override
public void onMarkerClick(Marker marker) {
displayMessage("Marker tapped: "
+ marker.getTitle() + ", at location "
+ marker.getPosition().latitude + ", "
+ marker.getPosition().longitude);
}
});
}
Puoi specificare un'immagine personalizzata come indicatore, ma l'SDK al momento non supporta l'etichettatura di queste immagini con testo. Per maggiori informazioni, vedi
Personalizzazione degli indicatori.
Testo mobile
Puoi aggiungere testo mobile in qualsiasi punto dell'app, purché l'attribuzione Google non sia coperta. L'SDK di navigazione non supporta l'ancoraggio del testo
a latitudine/longitudine sulla mappa o a un'etichetta. Per ulteriori informazioni, consulta la sezione Finestre informative.
Visualizza il limite di velocità
Puoi mostrare o nascondere in modo programmatico l'icona del limite di velocità.
Utilizza NavigationFragment.setSpeedLimitIconEnabled(), NavigationView.setSpeedLimitIconEnabled() o SupportNavigationFragment.setSpeedLimitIconEnabled() per visualizzare o nascondere l'icona del limite di velocità. Quando la funzionalità è attivata, l'icona del limite
di velocità viene visualizzata in basso durante le indicazioni. L'icona mostra il limite di velocità della strada su cui viaggia il veicolo. L'icona viene visualizzata solo nelle località in cui sono disponibili dati affidabili sui limiti di velocità.
// Display the Speed Limit icon
mNavFragment.setSpeedLimitIconEnabled(true);
L'icona del limite di velocità è temporaneamente nascosta quando viene visualizzato il pulsante di riposizionamento.
AUTO Consente all'SDK di navigazione di determinare la modalità appropriata in base alla posizione del dispositivo e all'ora locale.
FORCE_NIGHT forza l'attivazione della modalità notturna.
FORCE_DAY impone l'attivazione della modalità Giorno.
L'esempio seguente mostra come forzare l'attivazione della modalità notturna all'interno di un frammento di navigazione:
// Force night mode on.
mNavFragment.setForceNightMode(FORCE_NIGHT);
Visualizza elenco indicazioni stradali
Innanzitutto, crea la vista e aggiungila alla gerarchia.
setupDirectionsListView(){
// Create the view.
DirectionsListView directionsListView = new DirectionsListView(getApplicationContext());
// Add the view to your view hierarchy.
ViewGroup group = findViewById(R.id.directions_view);
group.addView(directionsListView);
// Add a button to your layout to close the directions list view.
ImageButton button = findViewById(R.id.close_directions_button); // this button is part of the container we hide in the next line.
button.setOnClickListener(
v -> findViewById(R.id.directions_view_container).setVisibility(View.GONE));
}
Assicurati di inoltrare gli eventi del ciclo di vita a DirectionsListView come
con NaviagtionView. Ad esempio:
Quando l'interfaccia utente contiene troppe informazioni, puoi ridurre il disordine visualizzando meno percorsi alternativi rispetto a quelli predefiniti (due) o senza vedere affatto percorsi alternativi. Puoi configurare questa opzione prima di recuperare le route chiamando il metodo RoutingOptions.alternateRoutesStrategy() con uno dei seguenti valori di enumerazione:
Valore di enumerazione
Descrizione
AlternateRoutesStrategy.SHOW_ALL
Predefinita. Visualizza fino a due percorsi alternativi.
AlternateRoutesStrategy.SHOW_ONE
Visualizza un percorso alternativo (se disponibile).
AlternateRoutesStrategy.SHOW_NONE
Nasconde i percorsi alternativi.
Esempio
Il seguente esempio di codice mostra come nascondere del tutto le route alternative.
RoutingOptions routingOptions = new RoutingOptions();
routingOptions.alternateRoutesStrategy(AlternateRoutesStrategy.SHOW_NONE);
navigator.setDestinations(destinations, routingOptions, displayOptions);