เพิ่มการเติมข้อมูลสถานที่อัตโนมัติในแบบฟอร์มที่อยู่

เมื่อกรอกที่อยู่ในการจัดส่ง ข้อมูลสำหรับการเรียกเก็บเงิน หรือข้อมูลกิจกรรม การเปิดใช้แบบฟอร์มที่มีฟีเจอร์เติมข้อความอัตโนมัติจะช่วยให้ผู้ใช้ลดการกดแป้นพิมพ์และข้อผิดพลาดเมื่อป้อนข้อมูลที่อยู่ บทแนะนำนี้จะอธิบายถึงขั้นตอนที่จำเป็นในการเปิดใช้งานช่องป้อนข้อมูลด้วย Place Autocomplete และเติมข้อมูลในช่องที่อยู่ในแบบฟอร์มด้วยองค์ประกอบที่อยู่จากที่อยู่ที่ผู้ใช้เลือก และแสดงที่อยู่ที่เลือกบนแผนที่เพื่อช่วยในการยืนยันด้วยภาพ

วิดีโอ: ปรับปรุงแบบฟอร์มที่อยู่ด้วยฟีเจอร์เติมข้อความอัตโนมัติ

แบบฟอร์มที่อยู่

Android

iOS

เว็บไซต์

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

รับโค้ด

โคลนหรือดาวน์โหลด ที่เก็บ Google Places SDK สำหรับการสาธิต Android จาก GitHub

ดูกิจกรรมในเวอร์ชัน Java

    /*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.placesdemo;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.example.placesdemo.databinding.AutocompleteAddressActivityBinding;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.AddressComponent;
import com.google.android.libraries.places.api.model.AddressComponents;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.TypeFilter;
import com.google.android.libraries.places.api.net.PlacesClient;
import com.google.android.libraries.places.widget.Autocomplete;
import com.google.android.libraries.places.widget.model.AutocompleteActivityMode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static com.google.maps.android.SphericalUtil.computeDistanceBetween;

/**
 * Activity for using Place Autocomplete to assist filling out an address form.
 */
@SuppressWarnings("FieldCanBeLocal")
public class AutocompleteAddressActivity extends AppCompatActivity implements OnMapReadyCallback {

    private static final String TAG = "ADDRESS_AUTOCOMPLETE";
    private static final String MAP_FRAGMENT_TAG = "MAP";
    private LatLng coordinates;
    private boolean checkProximity = false;
    private SupportMapFragment mapFragment;
    private GoogleMap map;
    private Marker marker;
    private PlacesClient placesClient;
    private View mapPanel;
    private LatLng deviceLocation;
    private static final double acceptedProximity = 150;

    private AutocompleteAddressActivityBinding binding;

    View.OnClickListener startAutocompleteIntentListener = view -> {
        view.setOnClickListener(null);
        startAutocompleteIntent();
    };

    private final ActivityResultLauncher<Intent> startAutocomplete = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent intent = result.getData();
                    if (intent != null) {
                        Place place = Autocomplete.getPlaceFromIntent(intent);

                        // Write a method to read the address components from the Place
                        // and populate the form with the address components
                        Log.d(TAG, "Place: " + place.getAddressComponents());
                        fillInAddress(place);
                    }
                } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                    // The user canceled the operation.
                    Log.i(TAG, "User canceled autocomplete");
                }
            });

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        binding.autocompleteAddress1.setOnClickListener(startAutocompleteIntentListener);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = AutocompleteAddressActivityBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Retrieve a PlacesClient (previously initialized - see MainActivity)
        placesClient = Places.createClient(this);

        // Attach an Autocomplete intent to the Address 1 EditText field
        binding.autocompleteAddress1.setOnClickListener(startAutocompleteIntentListener);

        // Update checkProximity when user checks the checkbox
        CheckBox checkProximityBox = findViewById(R.id.checkbox_proximity);
        checkProximityBox.setOnCheckedChangeListener((view, isChecked) -> {
            // Set the boolean to match user preference for when the Submit button is clicked
            checkProximity = isChecked;
        });

        // Submit and optionally check proximity
        Button saveButton = findViewById(R.id.autocomplete_save_button);
        saveButton.setOnClickListener(v -> saveForm());

        // Reset the form
        Button resetButton = findViewById(R.id.autocomplete_reset_button);
        resetButton.setOnClickListener(v -> clearForm());
    }

    private void startAutocompleteIntent() {

        // Set the fields to specify which types of place data to
        // return after the user has made a selection.
        List<Place.Field> fields = Arrays.asList(Place.Field.ADDRESS_COMPONENTS,
                Place.Field.LAT_LNG, Place.Field.VIEWPORT);

        // Build the autocomplete intent with field, country, and type filters applied
        Intent intent = new Autocomplete.IntentBuilder(AutocompleteActivityMode.OVERLAY, fields)
                .setCountries(Arrays.asList("US"))
                .setTypesFilter(new ArrayList<String>() {{
                    add(TypeFilter.ADDRESS.toString().toLowerCase());
                }})
                .build(this);
        startAutocomplete.launch(intent);
    }

    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        map = googleMap;
        try {
            // Customise the styling of the base map using a JSON object defined
            // in a string resource.
            boolean success = map.setMapStyle(
                    MapStyleOptions.loadRawResourceStyle(this, R.raw.style_json));

            if (!success) {
                Log.e(TAG, "Style parsing failed.");
            }
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, "Can't find style. Error: ", e);
        }
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15f));
        marker = map.addMarker(new MarkerOptions().position(coordinates));
    }

    private void fillInAddress(Place place) {
        AddressComponents components = place.getAddressComponents();
        StringBuilder address1 = new StringBuilder();
        StringBuilder postcode = new StringBuilder();

        // Get each component of the address from the place details,
        // and then fill-in the corresponding field on the form.
        // Possible AddressComponent types are documented at https://goo.gle/32SJPM1
        if (components != null) {
            for (AddressComponent component : components.asList()) {
                String type = component.getTypes().get(0);
                switch (type) {
                    case "street_number": {
                        address1.insert(0, component.getName());
                        break;
                    }

                    case "route": {
                        address1.append(" ");
                        address1.append(component.getShortName());
                        break;
                    }

                    case "postal_code": {
                        postcode.insert(0, component.getName());
                        break;
                    }

                    case "postal_code_suffix": {
                        postcode.append("-").append(component.getName());
                        break;
                    }

                    case "locality":
                        binding.autocompleteCity.setText(component.getName());
                        break;

                    case "administrative_area_level_1": {
                        binding.autocompleteState.setText(component.getShortName());
                        break;
                    }

                    case "country":
                        binding.autocompleteCountry.setText(component.getName());
                        break;
                }
            }
        }

        binding.autocompleteAddress1.setText(address1.toString());
        binding.autocompletePostal.setText(postcode.toString());

        // After filling the form with address components from the Autocomplete
        // prediction, set cursor focus on the second address line to encourage
        // entry of sub-premise information such as apartment, unit, or floor number.
        binding.autocompleteAddress2.requestFocus();

        // Add a map for visual confirmation of the address
        showMap(place);
    }

    private void showMap(Place place) {
        coordinates = place.getLatLng();

        // It isn't possible to set a fragment's id programmatically so we set a tag instead and
        // search for it using that.
        mapFragment = (SupportMapFragment)
                getSupportFragmentManager().findFragmentByTag(MAP_FRAGMENT_TAG);

        // We only create a fragment if it doesn't already exist.
        if (mapFragment == null) {
            mapPanel = ((ViewStub) findViewById(R.id.stub_map)).inflate();
            GoogleMapOptions mapOptions = new GoogleMapOptions();
            mapOptions.mapToolbarEnabled(false);

            // To programmatically add the map, we first create a SupportMapFragment.
            mapFragment = SupportMapFragment.newInstance(mapOptions);

            // Then we add it using a FragmentTransaction.
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.confirmation_map, mapFragment, MAP_FRAGMENT_TAG)
                    .commit();
            mapFragment.getMapAsync(this);
        } else {
            updateMap(coordinates);
        }
    }

    private void updateMap(LatLng latLng) {
        marker.setPosition(latLng);
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f));
        if (mapPanel.getVisibility() == View.GONE) {
            mapPanel.setVisibility(View.VISIBLE);
        }
    }

    private void saveForm() {
        Log.d(TAG, "checkProximity = " + checkProximity);
        if (checkProximity) {
            checkLocationPermissions();
        } else {
            Toast.makeText(
                            this,
                            R.string.autocomplete_skipped_message,
                            Toast.LENGTH_SHORT)
                    .show();
        }
    }

    private void clearForm() {
        binding.autocompleteAddress1.setText("");
        binding.autocompleteAddress2.getText().clear();
        binding.autocompleteCity.getText().clear();
        binding.autocompleteState.getText().clear();
        binding.autocompletePostal.getText().clear();
        binding.autocompleteCountry.getText().clear();
        if (mapPanel != null) {
            mapPanel.setVisibility(View.GONE);
        }
        binding.autocompleteAddress1.requestFocus();
    }

    // Register the permissions callback, which handles the user's response to the
    // system permissions dialog. Save the return value, an instance of
    // ActivityResultLauncher, as an instance variable.
    private final ActivityResultLauncher<String> requestPermissionLauncher =
            registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
                if (isGranted) {
                    // Since ACCESS_FINE_LOCATION is the only permission in this sample,
                    // run the location comparison task once permission is granted.
                    // Otherwise, check which permission is granted.
                    getAndCompareLocations();
                } else {
                    // Fallback behavior if user denies permission
                    Log.d(TAG, "User denied permission");
                }
            });

    private void checkLocationPermissions() {
        if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            getAndCompareLocations();
        } else {
            requestPermissionLauncher.launch(
                    ACCESS_FINE_LOCATION);
        }
    }

    @SuppressLint("MissingPermission")
    private void getAndCompareLocations() {
        // TODO: Detect and handle if user has entered or modified the address manually and update
        // the coordinates variable to the Lat/Lng of the manually entered address. May use
        // Geocoding API to convert the manually entered address to a Lat/Lng.
        LatLng enteredLocation = coordinates;
        map.setMyLocationEnabled(true);

        FusedLocationProviderClient fusedLocationClient =
                LocationServices.getFusedLocationProviderClient(this);

        fusedLocationClient.getLastLocation()
                .addOnSuccessListener(this, location -> {
                    // Got last known location. In some rare situations this can be null.
                    if (location == null) {
                        return;
                    }

                    deviceLocation = new LatLng(location.getLatitude(), location.getLongitude());
                    Log.d(TAG, "device location = " + deviceLocation);
                    Log.d(TAG, "entered location = " + enteredLocation.toString());

                    // Use the computeDistanceBetween function in the Maps SDK for Android Utility Library
                    // to use spherical geometry to compute the distance between two Lat/Lng points.
                    double distanceInMeters = computeDistanceBetween(deviceLocation, enteredLocation);
                    if (distanceInMeters <= acceptedProximity) {
                        Log.d(TAG, "location matched");
                        // TODO: Display UI based on the locations matching
                    } else {
                        Log.d(TAG, "location not matched");
                        // TODO: Display UI based on the locations not matching
                    }
                });
    }
}
    

กำลังเปิดใช้ API

หากต้องการใช้คำแนะนำเหล่านี้ คุณต้องเปิดใช้ API ต่อไปนี้ใน Google Cloud Console

โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าที่หัวข้อตั้งค่าโปรเจ็กต์ Google Cloud

การเพิ่มการเติมข้อความอัตโนมัติในช่องป้อนข้อมูล

ส่วนนี้จะอธิบายวิธีเพิ่มการเติมสถานที่อัตโนมัติในแบบฟอร์มที่อยู่

การเพิ่มวิดเจ็ตเติมข้อความอัตโนมัติเกี่ยวกับสถานที่

ใน Android คุณสามารถเพิ่มวิดเจ็ตเติมข้อความอัตโนมัติโดยใช้ Intent การเติมข้อความอัตโนมัติ ซึ่งเปิด "สถานที่เติมข้อความอัตโนมัติ" จากช่องป้อนข้อมูลที่อยู่บรรทัดที่ 1 ซึ่งผู้ใช้จะเริ่มป้อนที่อยู่ เมื่อเริ่มพิมพ์ ผู้ใช้จะสามารถเลือกที่อยู่จากรายการการคาดคะเนจากการเติมข้อความอัตโนมัติ

ขั้นแรก ให้เตรียมตัวเปิดกิจกรรมโดยใช้ ActivityResultLauncher ที่จะฟังผลลัพธ์จากกิจกรรมที่เปิดใช้งาน โค้ดเรียกกลับผลลัพธ์จะมีออบเจ็กต์สถานที่ที่สอดคล้องกับที่อยู่ที่ผู้ใช้เลือกจากการคาดคะเนจากการเติมข้อความอัตโนมัติ

    private final ActivityResultLauncher<Intent> startAutocomplete = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent intent = result.getData();
                    if (intent != null) {
                        Place place = Autocomplete.getPlaceFromIntent(intent);

                        // Write a method to read the address components from the Place
                        // and populate the form with the address components
                        Log.d(TAG, "Place: " + place.getAddressComponents());
                        fillInAddress(place);
                    }
                } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                    // The user canceled the operation.
                    Log.i(TAG, "User canceled autocomplete");
                }
            });

ต่อไป ให้กำหนดพร็อพเพอร์ตี้ของช่อง ตำแหน่ง และประเภทของพร็อพเพอร์ตี้ของการเติมข้อความอัตโนมัติใน Place แล้วสร้างด้วย Autocomplete.IntentBuilder ขั้นตอนสุดท้าย ให้เปิด Intent โดยใช้ ActivityResultLauncher ที่กำหนดไว้ในตัวอย่างโค้ดก่อนหน้านี้

    private void startAutocompleteIntent() {

        // Set the fields to specify which types of place data to
        // return after the user has made a selection.
        List<Place.Field> fields = Arrays.asList(Place.Field.ADDRESS_COMPONENTS,
                Place.Field.LAT_LNG, Place.Field.VIEWPORT);

        // Build the autocomplete intent with field, country, and type filters applied
        Intent intent = new Autocomplete.IntentBuilder(AutocompleteActivityMode.OVERLAY, fields)
                .setCountries(Arrays.asList("US"))
                .setTypesFilter(new ArrayList<String>() {{
                    add(TypeFilter.ADDRESS.toString().toLowerCase());
                }})
                .build(this);
        startAutocomplete.launch(intent);
    }

การจัดการที่อยู่ที่แสดงผลโดยการเติมข้อความอัตโนมัติในสถานที่

การกำหนด ActivityResultLauncher ก่อนหน้านี้ยังระบุสิ่งที่ควรทำเมื่อแสดงผลลัพธ์กิจกรรมในโค้ดเรียกกลับอีกด้วย หากผู้ใช้เลือกการคาดการณ์ ระบบจะส่งการคาดการณ์ใน Intent ที่อยู่ในออบเจ็กต์ผลลัพธ์ เนื่องจาก Intent สร้างขึ้นโดย Autocomplete.IntentBuilder เมธอด Autocomplete.getPlaceFromIntent() จึงสามารถดึงออบเจ็กต์ Place จากออบเจ็กต์ดังกล่าวได้

    private final ActivityResultLauncher<Intent> startAutocomplete = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent intent = result.getData();
                    if (intent != null) {
                        Place place = Autocomplete.getPlaceFromIntent(intent);

                        // Write a method to read the address components from the Place
                        // and populate the form with the address components
                        Log.d(TAG, "Place: " + place.getAddressComponents());
                        fillInAddress(place);
                    }
                } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                    // The user canceled the operation.
                    Log.i(TAG, "User canceled autocomplete");
                }
            });

จากนั้นเรียกใช้ Place.getAddressComponents() และจับคู่องค์ประกอบที่อยู่แต่ละรายการกับช่องป้อนข้อมูลที่ตรงกันในแบบฟอร์มที่อยู่ โดยใส่ค่าจากตำแหน่งที่ผู้ใช้เลือกลงในช่อง

มีการแชร์ตัวอย่างการใช้งานสำหรับการป้อนข้อมูลในช่องในแบบฟอร์มที่อยู่ในเมธอด fillInAddress ของโค้ดตัวอย่างที่ให้ไว้ในส่วนรับโค้ดของหน้านี้

การบันทึกข้อมูลที่อยู่จากการคาดคะเนแทนที่อยู่ที่ป้อนด้วยตนเองช่วยให้มั่นใจได้ว่าที่อยู่มีความถูกต้อง ทำให้มั่นใจได้ว่าที่อยู่นั้นเป็นที่รับทราบและนำส่งไปยังได้ และลดการกดแป้นพิมพ์ของผู้ใช้

ข้อควรพิจารณาเมื่อใช้การเติมข้อความอัตโนมัติ

Place Autocomplete มีตัวเลือกหลากหลายที่ช่วยให้มีความยืดหยุ่นในการใช้งาน หากคุณต้องการใช้มากกว่าแค่วิดเจ็ต คุณสามารถใช้บริการหลายอย่างร่วมกันเพื่อให้ได้สิ่งที่คุณต้องการในการจับคู่สถานที่ในลักษณะที่ถูกต้อง

  • สำหรับแบบฟอร์ม ADDRESS ให้ตั้งค่าพารามิเตอร์ประเภทเป็น address เพื่อจำกัดการจับคู่กับที่อยู่แบบเต็ม ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทที่คำขอเติมข้อมูลสถานที่อัตโนมัติรองรับ

  • กำหนดข้อจำกัดและอคติที่เหมาะสม หากคุณไม่ต้องการค้นหาทั่วโลก มีพารามิเตอร์จำนวนหนึ่งที่สามารถใช้การให้น้ำหนักพิเศษหรือจำกัดการจับคู่ที่ตรงกันเฉพาะบางภูมิภาคเท่านั้น

    • ใช้ RectangularBounds เพื่อกำหนดขอบเขตรูปสี่เหลี่ยมผืนผ้าเพื่อจำกัดพื้นที่ ใช้ setLocationRestriction() เพื่อให้แน่ใจว่าระบบจะแสดงผลเฉพาะที่อยู่ในพื้นที่เหล่านั้นเท่านั้น

    • ใช้ setCountries() เพื่อจำกัดการตอบกลับเฉพาะในบางประเทศ

  • ปล่อยให้ช่องแก้ไขได้ในกรณีที่การค้นหาบางช่องหายไปจากการจับคู่ และให้ลูกค้าอัปเดตที่อยู่ได้หากจำเป็น เนื่องจากที่อยู่ส่วนใหญ่ที่ส่งคืนโดยการเติมข้อมูลสถานที่อัตโนมัติไม่มีหมายเลขสถานที่ย่อย เช่น หมายเลขอพาร์ตเมนต์ ห้องชุด หรือหมายเลขห้อง คุณจึงสามารถย้ายโฟกัสไปที่ที่อยู่บรรทัดที่ 2 เพื่อกระตุ้นให้ผู้ใช้กรอกข้อมูลดังกล่าวหากจำเป็น

การแสดงภาพการยืนยันที่อยู่

ผู้ใช้จะเห็นภาพการยืนยันที่อยู่บนแผนที่ ซึ่งถือเป็นส่วนหนึ่งของการป้อนที่อยู่ วิธีนี้จะช่วยให้ผู้ใช้มั่นใจได้ว่าที่อยู่นั้นถูกต้อง

รูปต่อไปนี้แสดงแผนที่ด้านล่างที่อยู่พร้อมหมุดที่ที่อยู่ที่ป้อน

ตัวอย่างต่อไปนี้เป็นไปตามขั้นตอนพื้นฐานในการเพิ่มแผนที่ใน Android โปรดดูรายละเอียดเพิ่มเติมในเอกสารประกอบ

กำลังเพิ่ม SupportMapFragment

ก่อนอื่นให้เพิ่มส่วนย่อย SupportMapFragment ลงในไฟล์ XML ของเลย์เอาต์

    <fragment
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:id="@+id/confirmation_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

จากนั้นเพิ่มส่วนย่อยด้วยการเขียนโปรแกรมหากยังไม่มี

    private void showMap(Place place) {
        coordinates = place.getLatLng();

        // It isn't possible to set a fragment's id programmatically so we set a tag instead and
        // search for it using that.
        mapFragment = (SupportMapFragment)
                getSupportFragmentManager().findFragmentByTag(MAP_FRAGMENT_TAG);

        // We only create a fragment if it doesn't already exist.
        if (mapFragment == null) {
            mapPanel = ((ViewStub) findViewById(R.id.stub_map)).inflate();
            GoogleMapOptions mapOptions = new GoogleMapOptions();
            mapOptions.mapToolbarEnabled(false);

            // To programmatically add the map, we first create a SupportMapFragment.
            mapFragment = SupportMapFragment.newInstance(mapOptions);

            // Then we add it using a FragmentTransaction.
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.confirmation_map, mapFragment, MAP_FRAGMENT_TAG)
                    .commit();
            mapFragment.getMapAsync(this);
        } else {
            updateMap(coordinates);
        }
    }

การรับแฮนเดิลลงในส่วนย่อยและลงทะเบียนโค้ดเรียกกลับ

  1. หากต้องการรับแฮนเดิลไปยัง Fragment ให้เรียกใช้เมธอด FragmentManager.findFragmentById แล้วส่งรหัสทรัพยากรของ Fragment ในไฟล์เลย์เอาต์ หากคุณเพิ่ม Fragment แบบไดนามิก ให้ข้ามขั้นตอนนี้ไปเนื่องจากคุณเรียกข้อมูลแฮนเดิลแล้ว

  2. เรียกใช้เมธอด getMapAsync เพื่อตั้งค่าโค้ดเรียกกลับใน Fragment

ตัวอย่างเช่น ถ้าคุณเพิ่มแฟรกเมนต์แบบคงที่

Kotlin



val mapFragment = supportFragmentManager
    .findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)

      

Java


SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
    .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

      

การจัดรูปแบบและเพิ่มเครื่องหมายลงในแผนที่

เมื่อแผนที่พร้อมแล้ว ให้กำหนดรูปแบบ จัดกล้องให้อยู่ตรงกลาง แล้วเพิ่มเครื่องหมายไว้ที่พิกัดของที่อยู่ที่ป้อน โค้ดต่อไปนี้ใช้การจัดรูปแบบที่กำหนดไว้ในออบเจ็กต์ JSON หรือคุณจะโหลดรหัสแผนที่ที่กำหนดไว้ด้วยการจัดรูปแบบ Maps ในระบบคลาวด์ก็ได้

    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        map = googleMap;
        try {
            // Customise the styling of the base map using a JSON object defined
            // in a string resource.
            boolean success = map.setMapStyle(
                    MapStyleOptions.loadRawResourceStyle(this, R.raw.style_json));

            if (!success) {
                Log.e(TAG, "Style parsing failed.");
            }
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, "Can't find style. Error: ", e);
        }
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15f));
        marker = map.addMarker(new MarkerOptions().position(coordinates));
    }

(ดูตัวอย่างโค้ดแบบเต็ม)

การปิดใช้การควบคุมแผนที่

เพื่อให้แผนที่เรียบง่ายโดยแสดงตำแหน่งโดยไม่มีตัวควบคุมแผนที่เพิ่มเติม (เช่น เข็มทิศ แถบเครื่องมือ หรือคุณลักษณะอื่นๆ ในตัว) ให้พิจารณาปิดใช้งานการควบคุมที่คุณรู้สึกว่าไม่จำเป็น ใน Android อีกตัวเลือกหนึ่งคือการเปิดใช้โหมด Lite เพื่อให้มีการโต้ตอบแบบจำกัด