แก้ไข UI การนําทาง

เมื่อใช้ Navigation SDK สําหรับ Android คุณจะปรับเปลี่ยนประสบการณ์ของผู้ใช้กับแผนที่ได้โดยการกําหนดตัวควบคุมและองค์ประกอบ UI ในตัวที่จะปรากฏบนแผนที่ นอกจากนี้ คุณยังปรับลักษณะที่ปรากฏของ UI การนำทางได้ด้วย โปรดดูหลักเกณฑ์เกี่ยวกับการแก้ไข UI การนําทางที่ยอมรับได้ที่หน้านโยบาย

เอกสารนี้อธิบายวิธีแก้ไขอินเทอร์เฟซผู้ใช้ของแผนที่ 2 วิธี ได้แก่

ตัวควบคุม UI ของแผนที่

เราขอแนะนำให้ใช้การควบคุม UI ของแผนที่เพื่อวางองค์ประกอบ UI ที่กําหนดเองในมุมมองการนําทางเพื่อให้วางองค์ประกอบในตําแหน่งที่เหมาะสม เมื่อเลย์เอาต์ในตัวมีการเปลี่ยนแปลง Navigation SDK สำหรับ Android จะจัดตำแหน่งตัวควบคุมที่กำหนดเองใหม่โดยอัตโนมัติ คุณตั้งค่ามุมมองการควบคุมที่กำหนดเองได้ครั้งละ 1 มุมมองสำหรับแต่ละตำแหน่ง หากการออกแบบต้องใช้องค์ประกอบ UI หลายรายการ คุณสามารถวางองค์ประกอบเหล่านั้นใน ViewGroup และส่งไปยังเมธอด setCustomControl

setCustomControl method ระบุตําแหน่งตามที่กําหนดไว้ใน CustomControlPosition enum ดังนี้

  • SECONDARY_HEADER (ปรากฏในโหมดแนวตั้งเท่านั้น)
  • BOTTOM_START_BELOW
  • BOTTOM_END_BELOW
  • FOOTER
ตำแหน่งการควบคุมที่กำหนดเองสำหรับการวางแนวตั้ง
ตำแหน่งการควบคุมที่กำหนดเองสำหรับการวางแนวตั้ง
ตำแหน่งการควบคุมที่กำหนดเองสำหรับการวางแนวนอน
ตำแหน่งการควบคุมที่กำหนดเองสำหรับการวางแนวนอน

เพิ่มการควบคุมที่กำหนดเอง

  1. สร้าง Android View ด้วยองค์ประกอบ UI หรือ 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 view และตําแหน่งตัวควบคุมที่กําหนดเองที่เลือก

ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้จะนำส่วนหัวรองที่กำหนดเองออกและกลับไปที่เนื้อหาเริ่มต้น

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 รวมถึงองค์ประกอบ UI ของ Nav SDK เช่น ปุ่มจัดกึ่งกลางใหม่และโลโก้ Google จะวางอยู่เหนือส่วนท้ายของการควบคุมที่กำหนดเอง ตำแหน่งเริ่มต้นของสัญลักษณ์ลูกศรจะพิจารณาความสูงของส่วนท้ายที่กำหนดเอง

ใน landscape mode ส่วนท้ายที่กำหนดเองจะมีขนาดครึ่งความกว้างและจัดชิดกับด้านเริ่มต้น (ด้านซ้ายใน LTR) เช่นเดียวกับการ์ดเวลาถึงโดยประมาณของ Nav SDK การควบคุมที่กำหนดเองในตำแหน่ง CustomControlPosition.BOTTOM_START_BELOW และองค์ประกอบ UI ของ Nav SDK เช่น ปุ่มจัดกึ่งกลางใหม่และโลโก้ Google จะวางอยู่เหนือส่วนท้ายของการควบคุมที่กำหนดเอง การควบคุมที่กำหนดเองในCustomControlPosition.BOTTOM_END_BELOW ตำแหน่งและองค์ประกอบ UI ของ Nav SDK ตลอดขอบด้านท้าย (ด้านขวาใน LTR) จะยังคงอยู่ตรงกับด้านล่างของแผนที่ ตำแหน่งเริ่มต้นของสัญลักษณ์ลูกศรจะไม่เปลี่ยนแปลงเมื่อมีส่วนท้ายที่กำหนดเอง เนื่องจากส่วนท้ายจะไม่ขยายไปถึงด้านท้ายของแผนที่

การควบคุมที่กำหนดเองในตำแหน่ง CustomControlPosition.BOTTOM_START_BELOW และ CustomControlPosition.BOTTOM_END_BELOW รวมถึงองค์ประกอบ UI ของ Nav SDK เช่น ปุ่มจัดกึ่งกลางใหม่และโลโก้ Google จะวางอยู่เหนือส่วนท้ายของการควบคุมที่กำหนดเอง

อุปกรณ์เสริม UI ของแผนที่

Navigation SDK สำหรับ Android มีอุปกรณ์เสริม UI ที่ปรากฏขึ้นระหว่างการนำทาง ซึ่งคล้ายกับอุปกรณ์เสริมที่อยู่ในแอปพลิเคชัน Google Maps สำหรับ Android คุณสามารถปรับระดับการมองเห็นหรือลักษณะที่ปรากฏของตัวควบคุมเหล่านี้ได้ตามที่อธิบายไว้ในส่วนนี้ การเปลี่ยนแปลงที่คุณทำที่นี่จะแสดงในเซสชันการนําทางถัดไป

โปรดดูหลักเกณฑ์เกี่ยวกับการแก้ไข UI การนําทางที่ยอมรับได้ในหน้านโยบาย

ดูโค้ด

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() เพื่อเปลี่ยนธีมของส่วนหัวการนำทางและตัวบ่งชี้การเลี้ยวถัดไปที่ปรากฏใต้ส่วนหัว (หากมี)

คุณสามารถตั้งค่าแอตทริบิวต์ต่อไปนี้ได้

ประเภทแอตทริบิวต์Attributes
สีพื้นหลัง
  • โหมดกลางวันหลัก - สีของส่วนหัวการนำทางในเวลากลางวัน
  • โหมดกลางวันรอง - สีของไฟเลี้ยวเลี้ยวถัดไปในเวลากลางวัน
  • โหมดกลางคืนหลัก - สีของส่วนหัวการนำทางในเวลากลางคืน
  • โหมดกลางคืนรอง - สีกลางคืนของไฟเลี้ยวเลี้ยวถัดไป
องค์ประกอบข้อความสำหรับวิธีการ
  • สีข้อความ
  • แบบอักษร
  • ขนาดข้อความของแถวแรก
  • ขนาดข้อความของแถวที่ 2
องค์ประกอบข้อความสำหรับขั้นตอนถัดไป
  • แบบอักษร
  • สีข้อความของค่าระยะทาง
  • ขนาดข้อความของค่าระยะทาง
  • สีข้อความของหน่วยวัดระยะทาง
  • ขนาดข้อความของหน่วยวัดระยะทาง
ไอคอนการขับขี่
  • สีของไอคอนการบังคับเครื่องบินขนาดใหญ่
  • สีของไอคอนการบังคับเลี้ยวขนาดเล็ก
คำแนะนำเลน
  • สีของเลนที่แนะนำ

ตัวอย่างต่อไปนี้แสดงวิธีตั้งค่าตัวเลือกการจัดรูปแบบ

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 ใช้ Google Maps API สำหรับเครื่องหมาย ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบของ 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();
}

การซ่อนเส้นทางอื่น

เมื่ออินเทอร์เฟซผู้ใช้มีข้อมูลมากเกินไป คุณสามารถลดความกระจัดกระจายได้โดยการแสดงเส้นทางอื่นน้อยกว่าค่าเริ่มต้น (2 เส้นทาง) หรือไม่แสดงเส้นทางอื่นเลย คุณสามารถกําหนดค่าตัวเลือกนี้ก่อนดึงข้อมูลเส้นทางได้โดยเรียกใช้RoutingOptions.alternateRoutesStrategy()วิธีที่มีค่าการแจกแจงค่าใดค่าหนึ่งต่อไปนี้

ค่าการแจงนับคำอธิบาย
AlternateRoutesStrategy.SHOW_ALL ค่าเริ่มต้น แสดงเส้นทางอื่นได้สูงสุด 2 เส้นทาง
AlternateRoutesStrategy.SHOW_ONE แสดงเส้นทางอื่น 1 เส้นทาง (หากมี)
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);

ตำแหน่งแถบความคืบหน้าของการเดินทาง

  • ด้านซ้ายของแถบจะสอดคล้องกับด้านซ้ายของเครื่องวัดความเร็ว โลโก้ Google และปุ่ม "จัดกึ่งกลางใหม่" (หากมองเห็น) โดยประมาณ ความกว้างคือ 12 dp
  • แถบความคืบหน้าของการเดินทางจะคงความสูงไว้แบบคงที่ แถบความคืบหน้าของการเดินทางจะปรับระดับการมองเห็นและความสูงตามจุดแบ่งที่กำหนดไว้ตามความสูงของหน้าจอ เพื่อปรับให้เข้ากับข้อจำกัดของพื้นที่แนวตั้งในอุปกรณ์ขนาดเล็ก จุดพักเหล่านี้ไม่เกี่ยวข้องกับการวางแนวของอุปกรณ์และพื้นที่ที่แผนที่ใช้บนหน้าจอจริง
  • ความสูงของหน้าจอ การแสดงแถบความคืบหน้าของการเดินทาง ความสูงของแถบความคืบหน้าของการเดินทาง ตำแหน่งแกน Y ของแถบความคืบหน้าของการเดินทาง
    ขนาดเล็ก: 0 dp - 519 dp ไม่แสดง ไม่มี ไม่มี
    กลาง: 520 dp - 599 dp แสดง 130 dp เหนือตัวควบคุมด้านข้างของจุดเริ่มต้น (มาตรความเร็ว / โลโก้ Google / ปุ่มจัดศูนย์ใหม่)
    ใหญ่: 600 dp ขึ้นไป แสดง 290 dp เหนือตัวควบคุมด้านข้างของจุดเริ่มต้น (มาตรความเร็ว / โลโก้ Google / ปุ่มจัดศูนย์ใหม่)
  • หากแถบความคืบหน้าของการเดินทางซ้อนทับกับการ์ดเลี้ยวหรือองค์ประกอบ UI การนำทางอื่นๆ แถบดังกล่าวจะปรากฏใต้องค์ประกอบอื่นๆ เหล่านั้น

Prompt Visibility API (เวอร์ชันทดลอง)

Prompt Visibility API ช่วยให้คุณหลีกเลี่ยงความขัดแย้งระหว่างองค์ประกอบ UI ที่ Navigation SDK สร้างขึ้นกับองค์ประกอบ UI ที่กําหนดเองของคุณได้โดยการเพิ่ม Listener เพื่อรับการเรียกกลับก่อนที่องค์ประกอบ UI ของ Navigation SDK กำลังจะปรากฏขึ้นและทันทีที่นําองค์ประกอบออก ดูข้อมูลเพิ่มเติม รวมถึงตัวอย่างโค้ดได้ที่ส่วน Prompt Visibility API ของหน้ากําหนดค่าการหยุดชะงักแบบเรียลไทม์