Dodawanie autouzupełniania miejsc do formularza adresowego

Podczas wypełniania adresu dostawy, informacji rozliczeniowych lub informacji o wydarzeniu włączenie formularzy z autouzupełnianiem miejsc pomaga użytkownikom ograniczyć liczbę naciśnięć klawiszy i błędów podczas wpisywania informacji adresowych. Z tego samouczka dowiesz się, jak włączyć pole do wprowadzania danych z autouzupełnianiem miejsc i wypełnić pola formularza adresowego komponentami adresu wybranego przez użytkownika, a także jak wyświetlić wybrany adres na mapie, aby ułatwić wizualne potwierdzenie.

Formularz adresowy z podpowiedziami autouzupełniania miejsc i wypełnionymi polami

Filmy: ulepszanie formularzy adresowych za pomocą autouzupełniania miejsc

Formularze adresowe

Android

iOS

Sieć

Google Maps Platform udostępnia widżet autouzupełniania miejsc na platformy mobilne i do internetu. Widżet pokazany na poprzednich ilustracjach udostępnia okno wyszukiwania z wbudowaną funkcją autouzupełniania, którą można nawet zoptymalizować pod kątem wyszukiwania w określonej lokalizacji.

Pobierz kod

Sklonuj lub pobierz z GitHuba repozytorium z wersjami demonstracyjnymi pakietu SDK Miejsc Google na Androida.

Wyświetl wersję aktywności w języku 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 static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static com.google.maps.android.SphericalUtil.computeDistanceBetween;

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.EdgeToEdge;
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.AutocompletePrediction;
import com.google.android.libraries.places.api.model.AutocompleteSessionToken;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.model.PlaceTypes;
import com.google.android.libraries.places.api.net.FetchPlaceRequest;
import com.google.android.libraries.places.api.net.PlacesClient;
import com.google.android.libraries.places.widget.PlaceAutocomplete;
import java.util.Arrays;
import java.util.List;

/** 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) {
                                AutocompletePrediction prediction =
                                        PlaceAutocomplete.getPredictionFromIntent(intent);
                                AutocompleteSessionToken sessionToken =
                                        PlaceAutocomplete.getSessionTokenFromIntent(intent);
                                if (prediction != null) {
                                    List<Place.Field> fields =
                                            Arrays.asList(
                                                    Place.Field.ADDRESS_COMPONENTS,
                                                    Place.Field.LOCATION,
                                                    Place.Field.VIEWPORT);
                                    FetchPlaceRequest request =
                                            FetchPlaceRequest.builder(
                                                            prediction.getPlaceId(), fields)
                                                    .setSessionToken(sessionToken)
                                                    .build();
                                    placesClient
                                            .fetchPlace(request)
                                            .addOnSuccessListener(
                                                    response -> {
                                                        Place place = response.getPlace();
                                                        // 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);
                                                    })
                                            .addOnFailureListener(
                                                    exception -> {
                                                        Log.e(
                                                                TAG,
                                                                "Place not found: "
                                                                        + exception.getMessage());
                                                    });
                                }
                            }
                        } 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() {
        // Build the autocomplete intent with country and type filters applied
        Intent intent =
                new PlaceAutocomplete.IntentBuilder()
                        .setCountries(List.of("US"))
                        .setTypesFilter(List.of(PlaceTypes.ADDRESS))
                        .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.getLocation();

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

    

Włączam interfejsy API

Aby wdrożyć te rekomendacje, musisz włączyć w konsoli Google Cloud te interfejsy API:

Więcej informacji o konfiguracji znajdziesz w artykule Konfigurowanie projektu w chmurze Google.

Dodawanie autouzupełniania do pól do wprowadzania danych

W tej sekcji opisano, jak dodać autouzupełnianie miejsc do formularza adresowego.

Dodawanie widżetu autouzupełniania miejsc

W Androidzie możesz dodać widżet autouzupełniania za pomocą intencji autouzupełniania, która uruchamia autouzupełnianie miejsc z pola do wprowadzania danych Pierwszy wiersz adresu, w którym użytkownik zacznie wpisywać adres. Gdy zacznie wpisywać, będzie mogła wybrać swój adres z listy podpowiedzi autouzupełniania.

Najpierw przygotuj program uruchamiający aktywność za pomocą ActivityResultLauncher, który będzie nasłuchiwać wyniku z uruchomionej aktywności. Wywołanie zwrotne wyniku będzie zawierać obiekt Place odpowiadający adresowi wybranemu przez użytkownika z podpowiedzi autouzupełniania.

    private final ActivityResultLauncher<Intent> startAutocomplete =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == Activity.RESULT_OK) {
                            Intent intent = result.getData();
                            if (intent != null) {
                                AutocompletePrediction prediction =
                                        PlaceAutocomplete.getPredictionFromIntent(intent);
                                AutocompleteSessionToken sessionToken =
                                        PlaceAutocomplete.getSessionTokenFromIntent(intent);
                                if (prediction != null) {
                                    List<Place.Field> fields =
                                            Arrays.asList(
                                                    Place.Field.ADDRESS_COMPONENTS,
                                                    Place.Field.LOCATION,
                                                    Place.Field.VIEWPORT);
                                    FetchPlaceRequest request =
                                            FetchPlaceRequest.builder(
                                                            prediction.getPlaceId(), fields)
                                                    .setSessionToken(sessionToken)
                                                    .build();
                                    placesClient
                                            .fetchPlace(request)
                                            .addOnSuccessListener(
                                                    response -> {
                                                        Place place = response.getPlace();
                                                        // 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);
                                                    })
                                            .addOnFailureListener(
                                                    exception -> {
                                                        Log.e(
                                                                TAG,
                                                                "Place not found: "
                                                                        + exception.getMessage());
                                                    });
                                }
                            }
                        } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                            // The user canceled the operation.
                            Log.i(TAG, "User canceled autocomplete");
                        }
                    });

Następnie zdefiniuj pola, lokalizację i właściwości typu intencji autouzupełniania miejsc i utwórz ją za pomocą Autocomplete.IntentBuilder. Na koniec uruchom intencję, używając zmiennej ActivityResultLauncher zdefiniowanej w poprzednim przykładowym kodzie.

    private void startAutocompleteIntent() {
        // Build the autocomplete intent with country and type filters applied
        Intent intent =
                new PlaceAutocomplete.IntentBuilder()
                        .setCountries(List.of("US"))
                        .setTypesFilter(List.of(PlaceTypes.ADDRESS))
                        .build(this);
        startAutocomplete.launch(intent);
    }

Obsługa adresu zwróconego przez autouzupełnianie miejsc

Zdefiniowanie wcześniej ActivityResultLauncher określiło również, co należy zrobić, gdy wynik aktywności zostanie zwrócony w wywołaniu zwrotnym. Jeśli użytkownik wybrał podpowiedź, zostanie ona dostarczona w intencji zawartej w obiekcie wyniku. Ponieważ intencja została utworzona przez Autocomplete.IntentBuilder, metoda Autocomplete.getPlaceFromIntent() może wyodrębnić z niej obiekt Place.

    private final ActivityResultLauncher<Intent> startAutocomplete =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == Activity.RESULT_OK) {
                            Intent intent = result.getData();
                            if (intent != null) {
                                AutocompletePrediction prediction =
                                        PlaceAutocomplete.getPredictionFromIntent(intent);
                                AutocompleteSessionToken sessionToken =
                                        PlaceAutocomplete.getSessionTokenFromIntent(intent);
                                if (prediction != null) {
                                    List<Place.Field> fields =
                                            Arrays.asList(
                                                    Place.Field.ADDRESS_COMPONENTS,
                                                    Place.Field.LOCATION,
                                                    Place.Field.VIEWPORT);
                                    FetchPlaceRequest request =
                                            FetchPlaceRequest.builder(
                                                            prediction.getPlaceId(), fields)
                                                    .setSessionToken(sessionToken)
                                                    .build();
                                    placesClient
                                            .fetchPlace(request)
                                            .addOnSuccessListener(
                                                    response -> {
                                                        Place place = response.getPlace();
                                                        // 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);
                                                    })
                                            .addOnFailureListener(
                                                    exception -> {
                                                        Log.e(
                                                                TAG,
                                                                "Place not found: "
                                                                        + exception.getMessage());
                                                    });
                                }
                            }
                        } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                            // The user canceled the operation.
                            Log.i(TAG, "User canceled autocomplete");
                        }
                    });

Następnie wywołaj Place.getAddressComponents() i dopasuj każdy komponent adresu do odpowiedniego pola do wprowadzania danych w formularzu adresu, wypełniając pole wartością z miejsca wybranego przez użytkownika.

Przykładowa implementacja wypełniania pól formularza adresu jest udostępniona w metodzie fillInAddress przykładowego kodu w sekcji Pobierz kod na tej stronie.

Pobieranie danych adresowych z podpowiedzi zamiast ręcznego wpisywania adresu pomaga zapewnić dokładność adresu, gwarantuje, że adres jest znany i można pod niego dostarczyć przesyłkę, oraz zmniejsza liczbę naciśnięć klawiszy przez użytkownika.

Uwagi dotyczące wdrażania autouzupełniania miejsc

Autouzupełnianie miejsc ma wiele opcji, które umożliwiają elastyczne wdrażanie, jeśli chcesz używać nie tylko widżetu. Możesz użyć kombinacji usług, aby uzyskać dokładnie to, czego potrzebujesz, i prawidłowo dopasować lokalizację.

  • W przypadku formularza ADRES ustaw parametr types na address, aby ograniczyć dopasowania do pełnych adresów ulic. Dowiedz się więcej o typach obsługiwanych w żądaniach autouzupełniania miejsc.

  • Jeśli nie musisz wyszukiwać na całym świecie, ustaw odpowiednie ograniczenia i preferencje. Istnieje wiele parametrów, których można użyć, aby faworyzować lub ograniczać dopasowanie do określonych regionów.

    • Użyj RectangularBounds, aby ustawić prostokątne granice, które ograniczą obszar, i setLocationRestriction(), aby upewnić się, że zwracane są tylko adresy z tych obszarów.

    • Użyj setCountries(), aby ograniczyć odpowiedzi do określonego zestawu krajów.

  • Pozostaw pola edytowalne na wypadek, gdyby niektóre pola nie zostały dopasowane, i umożliwiaj klientom aktualizowanie adresu w razie potrzeby. Większość adresów zwracanych przez autouzupełnianie miejsc nie zawiera numerów lokali, takich jak numery mieszkań, apartamentów czy jednostek, dlatego możesz przenieść kursor do pola Adres – wiersz 2, aby zachęcić użytkownika do podania tych informacji, jeśli jest to konieczne.

wizualne potwierdzenie adresu,

W ramach wprowadzania adresu udostępnij użytkownikom wizualne potwierdzenie adresu na mapie. Dzięki temu użytkownicy mają dodatkową pewność, że adres jest prawidłowy.

Na ilustracji poniżej widać mapę pod adresem z pinezką w miejscu wpisanego adresu.

Formularz adresu ze znacznikiem na mapie potwierdzającym wybraną lokalizację

Ten przykład przedstawia podstawowe czynności związane z dodawaniem mapy w Androidzie. Więcej szczegółów znajdziesz w dokumentacji.

Dodawanie: SupportMapFragment

Najpierw dodaj fragment SupportMapFragment do pliku XML układu.

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

Następnie dodaj fragment programowo, jeśli jeszcze nie istnieje.

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

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

Pobieranie uchwytu do fragmentu i rejestrowanie wywołania zwrotnego

  1. Aby uzyskać uchwyt do fragmentu, wywołaj metodę FragmentManager.findFragmentById i przekaż jej identyfikator zasobu fragmentu w pliku układu. Jeśli fragment został dodany dynamicznie, pomiń ten krok, ponieważ uchwyt został już pobrany.

  2. Wywołaj metodę getMapAsync, aby ustawić wywołanie zwrotne we fragmencie.

Jeśli na przykład fragment został dodany statycznie:

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

      

Stylizowanie i dodawanie znacznika do mapy

Gdy mapa będzie gotowa, ustaw styl, wyśrodkuj kamerę i dodaj znacznik we współrzędnych wpisanego adresu. Poniższy kod używa stylu zdefiniowanego w obiekcie JSON. Możesz też wczytać identyfikator mapy, który został zdefiniowany za pomocą definiowania stylów map w Google Cloud.

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

(Zobacz pełny przykładowy kod)

Wyłączanie elementów sterujących mapą

Aby mapa była prosta i pokazywała lokalizację bez dodatkowych elementów sterujących (takich jak kompas, pasek narzędzi lub inne wbudowane funkcje), możesz wyłączyć elementy sterujące, których nie potrzebujesz. Na Androidzie możesz też włączyć wersję uproszczoną, aby zapewnić ograniczoną interaktywność.