请选择平台: Android iOS JavaScript

基本地点自动补全组件

Places UI Kit 的基本地点自动补全组件可让您添加一个单独的界面组件,该组件会在用户选择地点时返回地点 ID。该组件是一个全屏覆盖层,可为用户提供一个用于输入查询内容的搜索栏。当用户输入内容时,搜索栏下方会显示自动补全结果列表。当用户点按某个地点时,系统会向开发者返回一个仅包含地点 ID 的地点对象。此组件可自定义。

该组件通过 AutocompleteFilter 结构体获取地理边界和其他搜索参数。

响应提供了一个 Place 结构体,其中仅填充了 placeID 字段。

基本地点自动补全组件具有以下自定义选项:列表密度,以及是否包含位置图标。使用 AutocompleteUICustomization 结构体自定义组件。

您可以单独使用基本地点自动填充组件,也可以将其与其他 Google Maps Platform API 和服务搭配使用。

结算

每次打开该组件并进行查询时,系统都会向您收取费用。除非会话过期或从列表中选择某个地点,否则系统不会再针对该会话向您收费。

向应用添加基本自动补全组件

设置自动补全过滤条件参数(例如要返回的类型、要将结果限制到的国家/地区、结果的区域坐标,以及用户出发地的距离信息,如果已设置),就像在不使用 Places UI Kit 的情况下使用地点自动补全(新)一样。如需查看完整说明和用于创建自动补全过滤器的代码示例,请参阅地点自动补全(新)文档

创建自动补全过滤条件后,您可以创建一个包含界面自定义设置的结构。查看自定义选项和说明

然后,创建一个用于启动自定义的基本自动补全组件的按钮。

Swift

  Button("Search for a place") {
    showWidget.toggle()
  }
  .basicPlaceAutocomplete(
    show: $showWidget
     // ...
  )

查看完整示例

自定义基本自动补全组件

自定义内容

列表密度

您可以选择显示双行列表或多行列表。使用 AutocompleteUICustomization 类中的 AutocompleteListDensity 选项(.twoLine.multiLine)。如果您未指定列表密度,该组件将显示双行列表。

“位置”图标

您可以选择是否在结果列表中显示默认地点图标。使用 AutocompleteUICustomization 类中的 AutocompleteUIIcon.defaultIcon.noIcon)中的选项。

自定义主题

您可以指定一个主题来替换任何默认样式属性。您可以自定义地点详情组件的颜色、排版、间距、边框和边角。默认值为 PlacesMaterialTheme

未被覆盖的任何主题背景属性都使用默认样式。

Places 界面套件默认提供深色主题,因此您可能需要同时自定义深色主题和浅色主题。如需自定义深色主题,请向您的自定义主题添加 .darkattribution.darkModeColor 的值。

如需详细了解主题,请参阅自定义样式部分。

向基本自动补全组件添加内容和主题自定义设置

使用 AutocompleteUICustomization 类自定义基本自动补全组件。

Swift

let uiCustomization = AutocompleteUICustomization(
    listDensity: .multiLine,
    listItemIcon: .noIcon,
    theme: PlacesMaterialTheme()
)

示例

添加基本自动补全组件

此示例创建了一个带有按钮的自定义基本自动补全组件。已设置默认图标、双行列表密度和自定义主题。自动补全过滤器设置为查找拉斯维加斯及其附近与会计相关的地点。

Swift

  // Note: You must provide an API key in your app entry point first.
  // A demo view of the basic place autocomplete widget.
  public struct BasicPlaceAutocompleteView: View {
    @State private var fetchedPlace: Place?
    @State private var placesError: PlacesError?
    @State private var showWidget = false
    public var body: some View {
      let types: Set<PlaceType> = [.accounting]
      let countries: Set<String> = ["US"]
      let origin = CLLocation(latitude: 36.19030535579595, longitude: -115.25397680618019)
      let coordinateRegion = RectangularCoordinateRegion(
        northEast: CLLocationCoordinate2D(
          latitude: 36.25290087640495, longitude: -115.08025549571225),
        southWest: CLLocationCoordinate2D(latitude: 36.06607422287787, longitude: -115.33431432920293)
      )
      let regionCode = "US"
      let inputOffset = 10
      let filter = AutocompleteFilter(
        types: types,
        countries: countries,
        origin: origin,
        coordinateRegionBias: coordinateRegion,
        regionCode: regionCode)
      let uiCustomization = AutocompleteUICustomization(
        listDensity: .multiLine,
        listItemIcon: .noIcon,
        theme: PlacesMaterialTheme()
      )
      VStack {
        Button("Search for a place") {
          showWidget.toggle()
        }
        .basicPlaceAutocomplete(
          filter: filter,
          uiCustomization: uiCustomization ?? AutocompleteUICustomization(),
          show: $showWidget,
          onSelection: { place in
            guard let placeID = place.placeID else {
              self.placesError = .internal(
                "Could not fetch place details because place ID from selected suggestion not found."
              )
              return
            }
            Task {
              let placesClient = await PlacesClient.shared
              let fetchPlaceRequest = FetchPlaceRequest(
                placeID: placeID,
                placeProperties: [.displayName, .formattedAddress]
              )
              switch await placesClient.fetchPlace(with: fetchPlaceRequest) {
              case .success(let place):
                print("Fetched place: \(place)")
                self.fetchedPlace = place
              case .failure(let placesError):
                print("Failed to fetch place: \(placesError)")
                self.placesError = placesError
              }
            }
          },
          onError: { placesError in
            self.placesError = placesError
          }
        )
        if let placesError = $placesError.wrappedValue {
          Text(placesError.localizedDescription)
            .frame(maxWidth: .infinity, alignment: .leading)
        } else if let fetchedPlace = $fetchedPlace.wrappedValue {
          Text("\(fetchedPlace)")
            .frame(maxWidth: .infinity, alignment: .leading)
        }
      }
    }
  }

自定义主题

Swift

@Environment(\.colorScheme) var colorScheme
var theme: PlacesMaterialTheme {
    if customTheme {
      var theme = PlacesMaterialTheme()
      var color = PlacesMaterialColor()
      color.surface = (colorScheme == .dark ? .blue : .gray)
      color.outlineDecorative = (colorScheme == .dark ? .white : .black)
      color.onSurface = (colorScheme == .dark ? .yellow : .red)
      color.onSurfaceVariant = (colorScheme == .dark ? .white : .blue)
      color.onSecondaryContainer = (colorScheme == .dark ? .white : .red)
      color.secondaryContainer = (colorScheme == .dark ? .green : .purple)
      color.positive = (colorScheme == .dark ? .yellow : .red)
      color.primary = (colorScheme == .dark ? .yellow : .purple)
      color.info = (colorScheme == .dark ? .yellow : .purple)
      var shape = PlacesMaterialShape()
      shape.cornerRadius = 10
      var font = PlacesMaterialFont()
      font.labelLarge = .system(size: UIFontMetrics.default.scaledValue(for: 18))
      font.headlineMedium = .system(size: UIFontMetrics.default.scaledValue(for: 15))
      font.bodyLarge = .system(size: UIFontMetrics.default.scaledValue(for: 15))
      font.bodyMedium = .system(size: UIFontMetrics.default.scaledValue(for: 12))
      font.bodySmall = .system(size: UIFontMetrics.default.scaledValue(for: 11))
      var attribution = PlacesMaterialAttribution()
      attribution.lightModeColor = .black
      attribution.darkModeColor = .white
      theme.color = color
      theme.shape = shape
      theme.font = font
      theme.attribution = attribution
    } else {
      return PlacesMaterialTheme()
    }
}