diff --git a/demo-kotlin/app/src/main/java/com/example/placesdemo/AutocompleteAddressActivity.kt b/demo-kotlin/app/src/main/java/com/example/placesdemo/AutocompleteAddressActivity.kt index 6380d3e5..f751457b 100644 --- a/demo-kotlin/app/src/main/java/com/example/placesdemo/AutocompleteAddressActivity.kt +++ b/demo-kotlin/app/src/main/java/com/example/placesdemo/AutocompleteAddressActivity.kt @@ -40,12 +40,12 @@ 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.model.AddressComponents import com.google.android.libraries.places.api.model.Place import com.google.android.libraries.places.api.model.PlaceTypes import com.google.android.libraries.places.widget.Autocomplete import com.google.android.libraries.places.widget.model.AutocompleteActivityMode import com.google.maps.android.SphericalUtil.computeDistanceBetween -import java.util.* /** * Activity for using Place Autocomplete to assist filling out an address form. @@ -197,38 +197,19 @@ class AutocompleteAddressActivity : AppCompatActivity(R.layout.autocomplete_addr private fun fillInAddress(place: Place) { val components = place.addressComponents - val address1 = StringBuilder() - val postcode = 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 (component in components.asList()) { - when (component.types[0]) { - "street_number" -> { - address1.insert(0, component.name) - } - "route" -> { - address1.append(" ") - address1.append(component.shortName) - } - "postal_code" -> { - postcode.insert(0, component.name) - } - "postal_code_suffix" -> { - postcode.append("-").append(component.name) - } - "locality" -> binding.autocompleteCity.setText(component.name) - "administrative_area_level_1" -> { - binding.autocompleteState.setText(component.shortName) - } - "country" -> binding.autocompleteCountry.setText(component.name) - } + with (components.toAddress()) { + binding.autocompleteAddress1.setText(streetAddress) + binding.autocompletePostal.setText(fullPostalCode) + binding.autocompleteCity.setText(locality) + binding.autocompleteState.setText(adminArea) + binding.autocompleteCountry.setText(country) } } - 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 @@ -335,4 +316,55 @@ class AutocompleteAddressActivity : AppCompatActivity(R.layout.autocomplete_addr private val TAG = AutocompleteAddressActivity::class.java.simpleName private const val MAP_FRAGMENT_TAG = "MAP" } +} + +/** + * Data class representing a postal address. + * + * @property streetNumber The street number of the address. + * @property locality The locality or neighborhood of the address. + * @property route The street name or route of the address. + * @property postCode The primary part of the postal code. + * @property postCodeSuffix The optional suffix or extension of the postal code. + * @property adminArea The administrative area, such as state, province, or region. + * @property country The country of the address. + */ +private data class Address( + val streetNumber: String, + val locality: String, + val route: String, + val postCode: String, + val postCodeSuffix: String, + val adminArea: String, + val country: String +) { + val fullPostalCode: String + get() = listOf(postCode, postCodeSuffix).filter { it.isNotBlank() }.joinToString("-") + val streetAddress: String + get() = listOf(streetNumber, route).filter { it.isNotBlank() }.joinToString(" ") +} + +/** + * Converts an [AddressComponents] object to an [Address] object. + * + * This function iterates through the address components, creating a map where the key is the component type + * (e.g., "street_number", "route") and the value is the component name. It then uses this map to populate + * the fields of an [Address] object. + * + * If a specific address component type is not found in the [AddressComponents], the corresponding field in + * the [Address] object will be set to an empty string. + * + * @return An [Address] object representing the address information extracted from the [AddressComponents]. + */ +private fun AddressComponents.toAddress(): Address { + val addressMap = this.asList().associate { it.types[0] to it.name } + return Address( + streetNumber = addressMap["street_number"] ?: "", + route = addressMap["route"] ?: "", + postCode = addressMap["postal_code"] ?: "", + postCodeSuffix = addressMap["postal_code_suffix"] ?: "", + locality = addressMap["locality"] ?: "", + adminArea = addressMap["administrative_area_level_1"] ?: "", + country = addressMap["country"] ?: "" + ) } \ No newline at end of file