שינוי ממשק המשתמש של הניווט

באמצעות Navigation SDK ל-Android, אפשר לשנות את חוויית המשתמש במפה על ידי קביעת הרכיבים והפקדים המובנים של ממשק המשתמש שיופיעו במפה. אפשר גם לשנות את המראה החזותי של ממשק המשתמש של הניווט. בדף המדיניות מפורטות הנחיות לגבי שינויים מותרים בממשק המשתמש של הניווט.

במסמך הזה מוסבר איך לשנות את ממשק המשתמש של המפה בשתי דרכים:

פקדי ממשק המשתמש של המפה

פקדי ממשק המשתמש של המפה הם הדרך המומלצת למקם רכיבי ממשק משתמש מותאמים אישית בתצוגת הניווט, כדי להבטיח מיקום תקין. כשהפריסה המובנית משתנה, המערכת של Navigation SDK ל-Android ממקמת מחדש את הפקדים המותאמים אישית באופן אוטומטי. אפשר להגדיר תצוגה מותאמת אישית אחת של אמצעי הבקרה בכל פעם לכל מיקום. אם העיצוב שלכם דורש כמה רכיבי ממשק משתמש, תוכלו למקם אותם ב-ViewGroup ולהעביר אותו לשיטה setCustomControl.

ה-method‏ setCustomControl מספק את המיקומים כפי שמוגדרים ב-CustomControlPosition enum:

  • SECONDARY_HEADER (הסמל מופיע בפריסה לאורך בלבד)
  • BOTTOM_START_BELOW
  • BOTTOM_END_BELOW
  • FOOTER
מיקומי אמצעי בקרה בהתאמה אישית לכיוון לאורך.
מיקום מותאם אישית של אמצעי הבקרה בכיוון לאורך
מיקומי שליטה בהתאמה אישית לכיוון לרוחב.
מיקומי אמצעי בקרה בהתאמה אישית לכיוון לרוחב

הוספת אמצעי בקרה בהתאמה אישית

  1. יוצרים View של Android עם רכיב ממשק המשתמש או ה-ViewGroup בהתאמה אישית.
  2. מנפחים את ה-XML או יוצרים מופע של התצוגה בהתאמה אישית כדי לקבל מופע של התצוגה.
  3. משתמשים ב-NavigationView.setCustomControl או ב-SupportNavigationFragment.setCustomControl עם מיקום הבקרה המותאם אישית שנבחר מתוך CustomControlPosition enum.

    בדוגמה הבאה נוצר קטע קוד ומתווסף אמצעי בקרה מותאם אישית במיקום הכותרת המשנית.

     mNavFragment.setCustomControl(getLayoutInflater().
       inflate(R.layout.your_custom_control, null),
       CustomControlPosition.SECONDARY_HEADER);
     ```
    

הסרת אמצעי בקרה מותאם אישית

כדי להסיר אמצעי בקרה מותאם אישית, צריך להפעיל את השיטה setCustomControl עם פרמטר תצוגה null והמיקום שנבחר לאמצעי הבקרה המותאם אישית.

לדוגמה, קטע הקוד הבא מסיר כל כותרת משנית מותאמת אישית ומחזיר לתוכן ברירת המחדל:

mNavFragment.setCustomControl(null, CustomControlPosition.SECONDARY_HEADER);

מיקומי פקדים בהתאמה אישית

כותרת משנית

מיקום של רכיב בקרה מותאם אישית לכותרת משנית בפריסה לאורך.
מיקום של אמצעי בקרה מותאם אישית לכותרת משנית בפורמט לאורך

כדי להשתמש במיקום הזה של אמצעי הבקרה בהתאמה אישית, מעבירים את המיקום CustomControlPosition.SECONDARY_HEADER אל setCustomControl.

כברירת מחדל, פריסות המסך במצב ניווט כוללות מיקום לכותרת משנית שממוקמת מתחת לכותרת הראשית. הכותרת המשנית הזו מופיעה לפי הצורך, למשל כשמוצגת הנחיה לנתיב. האפליקציה יכולה להשתמש במיקום הכותרת המשני הזה בפריסת התוכן כדי להציג תוכן בהתאמה אישית. כשמשתמשים בתכונה הזו, אפשר לשלוט בכל תוכן ברירת המחדל של הכותרת המשנית. אם לתצוגת הניווט יש רקע, הרקע הזה נשאר במקומו ומכוסה על ידי הכותרת המשנית. כשהאפליקציה מסירה את הלחצן המותאם אישית, כל כותרת משנית שמוגדרת כברירת מחדל יכולה להופיע במקומו.

מיקום הכותרת המשנית בהתאמה אישית מיישר את הקצה העליון שלה עם הקצה התחתון של הכותרת הראשית. המיקום הזה נתמך רק ב-portrait mode. ב-landscape mode, הכותרת המשנית לא זמינה והפריסה לא משתנה.

התחלה בתחתית

מיקום מותאם אישית של אמצעי הבקרה בחלק התחתון של המסך בכיוון לאורך.
מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון של המסך בכיוון לאורך
מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון של המסך בכיוון לרוחב.
מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון של המסך בכיוון לרוחב

כדי להשתמש במיקום הזה של אמצעי הבקרה בהתאמה אישית, מעבירים את המיקום CustomControlPosition.BOTTOM_START_BELOW אל setCustomControl.

מיקום הלחצן המותאם אישית הזה נמצא בפינה הימנית התחתונה של המפה. גם ב-portrait mode וגם ב-landscape mode, הוא ממוקם מעל הכרטיס 'זמן הגעה משוער' ו/או הכותרת התחתונה בהתאמה אישית (או בחלק התחתון של המפה אם אף אחד מהם לא מופיע), ורכיבי Nav SDK, כולל הלחצן להצגה במרכז והלוגו של Google, זזים למעלה כדי להתאים לגובה של תצוגת אמצעי הבקרה בהתאמה אישית. אמצעי הבקרה הזה ממוקם בתוך גבולות המפה הגלויים, כך שכל מרווח פנימי שיתווסף לקצוות התחתון או העליון של המפה ישנה גם את המיקום של אמצעי הבקרה הזה.

הקצה התחתון

מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון של המסך בכיוון לאורך.
מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון לכיוון לאורך
מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון של המסך בכיוון לרוחב.
מיקום של אמצעי בקרה בהתאמה אישית בחלק התחתון של המסך בכיוון לרוחב

כדי להשתמש במיקום הזה של אמצעי הבקרה בהתאמה אישית, מעבירים את המיקום CustomControlPosition.BOTTOM_END_BELOW אל setCustomControl.

מיקום הלחצן המותאם אישית הזה נמצא בפינה התחתונה של המפה. ב-portrait mode, הוא ממוקם מעל הכרטיס של זמן ההגעה המשוער ו/או הכותרת התחתונה בהתאמה אישית (או בחלק התחתון של המפה אם אף אחד מהם לא מופיע), אבל ב-landscape mode הוא מיושר עם החלק התחתון של המפה. כל הרכיבים של Nav SDK שגלויים בצד הקצה (הצד השמאלי ב-LTR) מועברים למעלה כדי להתחשב בגובה של תצוגת הפקדים בהתאמה אישית. אמצעי הבקרה הזה ממוקם בתוך גבולות המפה הגלויים, כך שכל מרווח פנימי שיתווסף לקצוות התחתונים או לקצוות הצדדים של המפה ישנה גם את המיקום של אמצעי הבקרה הזה.

מיקום של רכיב בקרה מותאם אישית בכותרת התחתונה בכיוון לאורך.
מיקום של פקדים מותאמים אישית בכותרת התחתונה בכיוון לאורך
מיקום של רכיב בקרה בהתאמה אישית בכותרת התחתונה בכיוון לרוחב.
מיקום של אמצעי בקרה בהתאמה אישית בכותרת התחתונה בכיוון לרוחב

כדי להשתמש במיקום הזה של אמצעי הבקרה בהתאמה אישית, מעבירים את המיקום CustomControlPosition.FOOTER אל setCustomControl.

מיקום הבקרה בהתאמה אישית הזה מיועד לתצוגת כותרת תחתונה בהתאמה אישית. אם כרטיס זמן ההגעה המשוער של Nav SDK גלוי, הלחצן הזה יופיע מעליו. אם לא, הלחצן ייצב בחלק התחתון של המפה. בניגוד לפקדים המותאמים אישית BOTTOM_START_BELOW ו-BOTTOM_END_BELOW, הפקדים האלה ממוקמים מחוץ לגבולות המפה הגלויים. כלומר, כל תוספת של רווח למפה לא תשנה את המיקום של הפקדים האלה.

ב-portrait mode, הכותרת התחתונה בהתאמה אישית היא ברוחב מלא. אמצעי הבקרה בהתאמה אישית במיקומים CustomControlPosition.BOTTOM_START_BELOW ו-CustomControlPosition.BOTTOM_END_BELOW, וכן רכיבי ממשק המשתמש של Nav SDK כמו הלחצן להחזרת התצוגה למרכז והלוגו של Google, ממוקמים מעל לכותרת התחתונה של אמצעי הבקרה בהתאמה אישית. מיקום ברירת המחדל של החץ המעוקל מביאה בחשבון את גובה הכותרת התחתונה בהתאמה אישית.

ב-landscape mode, הכותרת התחתונה בהתאמה אישית היא ברוחב חצי ומותאמת לצד ההתחלה (הצד ימין ב-LTR), בדיוק כמו הכרטיס של זמן ההגעה המשוער ב-Nav SDK. אמצעי הבקרה בהתאמה אישית במיקום CustomControlPosition.BOTTOM_START_BELOW ורכיבי ממשק המשתמש של Nav SDK, כמו הלחצן למרכוז מחדש והלוגו של Google, ממוקמים מעל לכותרת התחתונה של אמצעי הבקרה בהתאמה אישית. אמצעי הבקרה בהתאמה אישית במיקום CustomControlPosition.BOTTOM_END_BELOW וכל רכיבי ממשק המשתמש של Nav SDK בצד הקצה (הצד השמאלי ב-LTR) נשארים מיושרים עם החלק התחתון של המפה. מיקום ברירת המחדל של החץ לא משתנה כשיש כותרת תחתונה מותאמת אישית, כי כותרת התחתונה לא נמשכת עד לקצה המפה.

אמצעי הבקרה בהתאמה אישית במיקומים CustomControlPosition.BOTTOM_START_BELOW ו-CustomControlPosition.BOTTOM_END_BELOW, וכן רכיבי ממשק המשתמש של Nav SDK כמו הלחצן להחזרת התצוגה למרכז והלוגו של Google, ממוקמים מעל לכותרת התחתונה של אמצעי הבקרה בהתאמה אישית.

אביזרים לממשק המשתמש של המפה

‏Navigation SDK ל-Android מספק אביזרי ממשק משתמש שמופיעים במהלך הניווט, בדומה לאלה שמופיעים באפליקציית מפות Google ל-Android. אפשר לשנות את ההצגה או את המראה החזותי של אמצעי הבקרה האלה, כפי שמתואר בקטע הזה. השינויים שיבוצעו כאן ישתקפו בסשן הניווט הבא.

בדף המדיניות מפורטות הנחיות לגבי שינויים מקובלים בממשק המשתמש של הניווט.

הצגת הקוד

package com.example.navsdkcustomization;

import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.CameraPerspective;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.libraries.navigation.ListenableResultFuture;
import com.google.android.libraries.navigation.NavigationApi;
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.SupportNavigationFragment;
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 SupportNavigationFragment mNavFragment;
  private GoogleMap 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 =
                (SupportNavigationFragment)
                    getSupportFragmentManager().findFragmentById(R.id.navigation_fragment);

            // Get the map.
            mNavFragment.getMapAsync(
                new OnMapReadyCallback() {
                  @Override
                  public void onMapReady(GoogleMap map) {
                    mMap = map;
                    // 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));

    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(BitmapDescriptorFactory.fromBitmap(destinationMarkerIcon))
              .title("Destination marker"));

      // Listen for a tap on the marker.
      mMap.setOnMarkerClickListener(
          new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
              displayMessage(
                  "Marker tapped: "
                      + marker.getTitle()
                      + ", at location "
                      + marker.getPosition().latitude
                      + ", "
                      + marker.getPosition().longitude);

              // The event has been handled.
              return true;
            }
          });
    }

    // Set the camera to follow the device location with 'TILTED' driving view.
    mMap.followMyLocation(CameraPerspective.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.builder().setPlaceIdString(placeId).build();
    } 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);
  }
}

שינוי הכותרת של תפריט הניווט

אפשר להשתמש בSupportNavigationFragment.setStylingOptions() או בNavigationView.setStylingOptions() כדי לשנות את העיצוב של כותרת הניווט ואת הסמנים של הפניות הבאות שמופיעים מתחת לכותרת כשהם זמינים.

אפשר להגדיר את המאפיינים הבאים:

סוג מאפייןמאפיינים
צבע הרקע
  • מצב יום ראשי – הצבע של כותרת הניווט בשעות היום
  • מצב יום משני – הצבע של נורית הפנייה הבאה בשעות היום
  • מצב לילה ראשי – הצבע של כותרת הניווט בלילה
  • מצב לילה משני – הצבע בלילה של האינדיקטור של הפניה הבאה
רכיבי טקסט להוראות
  • צבע טקסט
  • גופן
  • גודל הטקסט בשורה הראשונה
  • גודל הטקסט בשורה השנייה
רכיבי טקסט לשלבים הבאים
  • גופן
  • צבע הטקסט של ערך המרחק
  • גודל הטקסט של ערך המרחק
  • צבע הטקסט של יחידות המרחק
  • גודל הטקסט של יחידות המרחק
סמלי תמרון
  • הצבע של סמל התמרון הגדול
  • הצבע של סמל התמרון הקטן
הנחיה לבחירת נתיב
  • הצבע של הנתיבים המומלצים

בדוגמה הבאה מוסבר איך להגדיר אפשרויות עיצוב:

private SupportNavigationFragment mNavFragment;
mNavFragment = (SupportNavigationFragment) 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));

השבתה של שכבת התנועה

משתמשים בGoogleMap.setTrafficEnabled() כדי להפעיל או להשבית את שכבת התנועה במפה. ההגדרה הזו משפיעה על האינדיקציות של צפיפות התנועה שמוצגות במפה באופן כללי. עם זאת, היא לא משפיעה על דיווחי התנועה במסלול שנקבע על ידי הניווט.

private GoogleMap mMap;
// Get the map, and when the async call returns, setTrafficEnabled
// (callback will be on the UI thread)
mMap = mNavFragment.getMapAsync(navMap -> navMap.setTrafficEnabled(false));

הפעלת רמזורים ותמרורים

אתם יכולים להפעיל את הצגת הפנסים והסמלים של תמרורים במפה במהלך ניווט פעיל, כדי לקבל הקשר נוסף לגבי המסלולים והפעולות במהלך הנסיעה.

כברירת מחדל, רמזור ותמרור עצור מושבתים ב-Navigation SDK. כדי להפעיל את התכונה הזו, צריך להפעיל כל אחת מהתכונות בנפרד באמצעות הפונקציה DisplayOptions.

DisplayOptions displayOptions =
  new DisplayOptions().showTrafficLights(true).showStopSigns(true);

הוספת סמנים מותאמים אישית

‫Navigation SDK ל-Android משתמש עכשיו בממשקי ה-API של מפות Google לסימונים. מידע נוסף זמין במסמכי העזרה של Maps API.

טקסט צף

אפשר להוסיף טקסט צף בכל מקום באפליקציה, בתנאי שהוא לא מכסה את השיוך ל-Google. ב-Navigation SDK אין תמיכה בהצמדת טקסט לקו הרוחב/האורך במפה או לתווית. מידע נוסף זמין במאמר חלונות מידע.

הצגת מגבלת המהירות

אפשר להציג או להסתיר את סמל המהירות המותרת באופן פרוגרמטי. משתמשים בNavigationView.setSpeedLimitIconEnabled() או בSupportNavigationFragment.setSpeedLimitIconEnabled() כדי להציג או להסתיר את סמל מגבלת המהירות. כשהאפשרות הזו מופעלת, סמל המהירות המותרת מוצג בפינה התחתונה במהלך ההנחיות. הסמל מציג את מגבלת המהירות של הכביש שבו הרכב נוסע. הסמל מופיע רק במיקומים שבהם יש נתונים מהימנים לגבי מגבלות המהירות.

 // Display the Speed Limit icon
 mNavFragment.setSpeedLimitIconEnabled(true);

סמל המהירות המותרת מוסתר באופן זמני כשהלחצן להצגת המיקום במרכז המסך מוצג.

הגדרת מצב לילה

אפשר לשלוט באופן פרוגרמטי בהתנהגות של מצב הלילה. אפשר להשתמש בNavigationView.setForceNightMode() או בSupportNavigationFragment.setForceNightMode() כדי להפעיל או להשבית את מצב הלילה, או לאפשר ל-Navigation SDK ל-Android לשלוט בו.

  • AUTO מאפשרת ל-Navigation SDK לקבוע את המצב המתאים בהתאם למיקום המכשיר ולשעה המקומית.
  • FORCE_NIGHT מפעילה את מצב הלילה.
  • FORCE_DAY מפעילה את מצב היום.

בדוגמה הבאה מוצגת הפעלה מאולצת של מצב לילה בתוך קטע ניווט:

// Force night mode on.
mNavFragment.setForceNightMode(FORCE_NIGHT);

הצגת רשימת המסלולים

קודם יוצרים את התצוגה ומוסיפים אותה להיררכיה.

void 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));
}

חשוב להעביר אירועים במחזור החיים אל DirectionsListView בדיוק כמו שהם מועברים אל NavigationView. לדוגמה:

protected void onResume() {
  super.onResume();
  directionsListView.onResume();
}

הסתרת מסלולים חלופיים

אם ממשק המשתמש עמוס במידע רב מדי, תוכלו להציג פחות מסלולים חלופיים מברירת המחדל (שניים), או לא להציג מסלולים חלופיים בכלל. אפשר להגדיר את האפשרות הזו לפני שאתם מאחזרים את המסלולים, על ידי קריאה ל-method‏ RoutingOptions.alternateRoutesStrategy() עם אחד מערכי המנייה הבאים:

ערך מספורתיאור
AlternateRoutesStrategy.SHOW_ALL ברירת מחדל. מוצגים עד שני מסלולים חלופיים.
AlternateRoutesStrategy.SHOW_ONE מוצג מסלול חלופי אחד (אם יש כזה).
AlternateRoutesStrategy.SHOW_NONE הסתרת מסלולים חלופיים.

בדוגמת הקוד הבאה מוסבר איך להסתיר מסלולים חלופיים לגמרי.

RoutingOptions routingOptions = new RoutingOptions();
routingOptions.alternateRoutesStrategy(AlternateRoutesStrategy.SHOW_NONE);
navigator.setDestinations(destinations, routingOptions, displayOptions);

סרגל ההתקדמות של הנסיעה

מחוון ההתקדמות בנסיעה נוסף לתפריט הניווט.

סרגל ההתקדמות של הנסיעה הוא סרגל אנכי שמופיע בקצה השמאלי של המפה כשהניווט מתחיל. כשהאפשרות הזו מופעלת, מוצגת סקירה כללית של כל הנסיעה, יחד עם היעד והמיקום הנוכחי של המשתמש.

המפה מאפשרת למשתמשים לחזות במהירות בעיות שצפויות להתרחש, כמו פקקים, בלי צורך להתקרב למפה. לאחר מכן, הם יוכלו לשנות את מסלול הנסיעה לפי הצורך. אם המשתמש משנה את מסלול הנסיעה, סרגל ההתקדמות מתאפס כאילו נסיעה חדשה מתחילה מהנקודה הזו.

בסרגל התקדמות הנסיעה מוצגים אינדיקטורים של הסטטוסים הבאים:

  • הזמן שחלף במסלול – החלק של הנסיעה שחלף.

  • המיקום הנוכחי – המיקום הנוכחי של המשתמש בנסיעה.

  • סטטוס התנועה – הסטטוס של התנועה הצפויה.

  • יעד סופי – היעד הסופי של הנסיעה.

כדי להפעיל את סרגל ההתקדמות של הנסיעה, צריך להפעיל את השיטה setTripProgressBarEnabled() ב-NavigationView או ב-SupportNavigationFragment. לדוגמה:

// Enable the trip progress bar.
mNavFragment.setTripProgressBarEnabled(true);