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

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

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

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

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;
import androidx.activity.EdgeToEdge;

/**
 * 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) {
        // Enable edge-to-edge display. This must be called before calling super.onCreate().
        EdgeToEdge.enable(this);
        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

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

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

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

การเพิ่มวิดเจ็ต Place Autocomplete

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

ก่อนอื่น ให้เตรียมตัวเรียกใช้กิจกรรมโดยใช้ ActivityResultLauncher ซึ่งจะรอผลลัพธ์ จากกิจกรรมที่เปิด การเรียกกลับผลลัพธ์จะมีออบเจ็กต์ 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");
                }
            });

จากนั้นกำหนดฟิลด์ สถานที่ และพร็อพเพอร์ตี้ประเภทของ เจตนาการเติมข้อความอัตโนมัติของสถานที่ และสร้างด้วย 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);
    }

การจัดการที่อยู่ที่ Place Autocomplete แสดง

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

    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เมธอดของโค้ดตัวอย่างที่ระบุไว้ในส่วนรับโค้ดของหน้านี้

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

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

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

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

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

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

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

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

การยืนยันที่อยู่ด้วยภาพ

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

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

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

กำลังเพิ่มSupportMapFragment

ก่อนอื่น ให้เพิ่มSupportMapFragment Fragment ลงใน ไฟล์ 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"/>

จากนั้นให้เพิ่ม Fragment โดยอัตโนมัติหากยังไม่มี

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

รับแฮนเดิลไปยัง Fragment และลงทะเบียนการเรียกกลับ

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

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

เช่น หากคุณเพิ่ม 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 หรือคุณจะโหลดรหัสแผนที่ที่ กำหนดไว้ด้วยการจัดรูปแบบแผนที่ในระบบคลาวด์ก็ได้

    @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 เพื่อให้มีการโต้ตอบแบบจำกัด