Flutter地点选择器插件google_places_picker_advance的使用
Flutter地点选择器插件google_places_picker_advance的使用
Google Maps Place Picker
google_places_picker_advance 是一个基于 Flutter 的插件,通过 Google Maps 提供地点选择功能。
该项目依赖以下包:
- 使用 Flutter 官方的 
google_maps_flutter进行地图展示。 - 使用 Baseflow 的 
geolocator获取当前位置。 - 使用 hadrienlejard 的 
google_maps_webservice调用 Place 和 Geocoding API。 - 使用 kevmoo 的 
tuple构建器。 
支持
如果你觉得这个插件对你有用或节省了时间,请不要犹豫买杯咖啡支持我!😉
更多的咖啡因意味着未来可以开发更多有用的功能。
开始使用
获取 API 密钥
- 在 Google Cloud Console 获取 API 密钥。
 - 启用以下 API:
- Maps SDK for Android
 - Maps SDK for iOS
 - Maps JavaScript API
 - Places API
 - Geolocation API
 - Geocoding API
 
 
你也可以在这里找到详细的启用步骤:Google Maps 平台入门指南。
Android 配置
在 android/app/src/main/AndroidManifest.xml 中添加 API 密钥:
<manifest ...
  <application ...
    <meta-data android:name="com.google.android.geo.API_KEY"
               android:value="YOUR KEY HERE"/>
注意:从版本 3.0.0 开始,geolocator 插件切换到了 AndroidX 版本的支持库。因此你需要确保你的 Android 项目也升级到支持 AndroidX。详细说明可以查看 Flutter 官方文档。
快速解决方案:
- 在 
gradle.properties文件中添加以下内容:android.useAndroidX=true android.enableJetifier=true - 在 
android/app/build.gradle文件中设置compileSdkVersion为 32:android { compileSdkVersion 32 ... } - 将所有 
android.依赖替换为其 AndroidX 对应版本(完整列表可参考 AndroidX 迁移指南)。 
iOS 配置
在 ios/Runner/AppDelegate.m 中指定 API 密钥:
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#import "GoogleMaps/GoogleMaps.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:@"YOUR KEY HERE"];
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
在 Swift 代码中,同样在 ios/Runner/AppDelegate.swift 中指定 API 密钥:
import UIKit
import Flutter
import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("YOUR KEY HERE")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
同时,需要在 Info.plist 文件中添加以下内容以访问设备位置:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when open and in the background.</string>
此外,还需要在 XCode 项目中启用 Background Modes 功能,并选择 Location Updates。
最后,在 Info.plist 文件中添加以下键值对以启用嵌入式视图预览:
<key>io.flutter.embedded_views_preview</key>
<true/>
使用方法
基本使用
可以通过 Navigator 推动到新页面,或者直接作为任何小部件的子组件使用。
当用户在地图上选择一个地点时,它会通过 onPlacePicked 回调返回结果。
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => PlacePicker(
      apiKey: APIKeys.apiKey,   // 替换为你的 API 密钥
      onPlacePicked: (result) { 
        print(result.address); 
        Navigator.of(context).pop();
      },
      initialPosition: LatLng(37.7749, -122.4194), // 初始位置(旧金山)
      useCurrentLocation: true, // 使用当前设备位置
    ),
  ),
);
PickResult 参数说明
以下是 PickResult 的参数及其描述:
| 参数名称 | 类型 | 描述 | 
|---|---|---|
| placeId | String | 唯一标识地点的文本标识符。详见 PlaceId 文档。 | 
| geometry | Geometry | 包含地点的几何信息,通常包括地理位置和视口。 | 
| formattedAddress | String | 地点的人类可读地址,通常等同于邮政地址。 | 
| types | List<String> | 描述该地点特征的数组。详见 支持的类型列表。 | 
| addressComponents | List<AddressComponent> | 地址的相关组件数组。 | 
注:以下结果仅在使用自动完成搜索或设置 usePlaceDetailSearch 为 true 时可用。
PickResult 可选参数
| 参数名称 | 类型 | 描述 | 
|---|---|---|
| adrAddress | String | 地址的 adr microformat 表示形式。 | 
| formattedPhoneNumber | String | 地点的电话号码,以本地格式显示。 | 
| id | String | (未在 Google 文档中记录) | 
| reference | String | (未在 Google 文档中记录) | 
| icon | String | 地图上显示此结果建议的图标 URL。 | 
| name | String | 返回结果的人类可读名称。 | 
| openingHours | OpeningHoursDetail | 营业时间信息。 | 
| photos | List<Photo> | 包含图像引用的照片数组。 | 
| internationalPhoneNumber | String | 地点的国际格式电话号码。 | 
| priceLevel | PriceLevel | 地点的价格等级,范围为 0 到 4。 | 
| rating | num | 地点的评分,基于用户评论,范围为 1.0 到 5.0。 | 
| scope | String | (未记录) | 
| url | String | 地点的官方 Google 页面 URL。 | 
| vicinity | String | 简化地址,包括街道名称、门牌号和所在地区,但不包括省份、邮政编码或国家。 | 
| utcOffset | num | 此地点当前时区与 UTC 的偏移量(分钟)。 | 
| website | String | 地点的权威网站。 | 
| reviews | List<Review> | 最多包含五个评论的 JSON 数组。 | 
更多关于结果的信息可以参考 Google Places API 文档。
PlacePicker 参数说明
| 参数名称 | 类型 | 描述 | 
|---|---|---|
| apiKey | String | 必填项,Google Maps API 密钥。 | 
| onPlacePicked | Callback(PickResult) | 用户选择地点并确认后触发回调。 | 
| initialPosition | LatLng | 初始地图中心位置。如果 useCurrentLocation 设置为 true,将尝试获取设备的当前位置。 | 
| useCurrentLocation | bool | 是否使用设备的当前位置作为初始中心位置。 | 
| desiredLocationAccuracy | LocationAccuracy | 获取当前位置的精度,默认为高精度。 | 
| hintText | String | 搜索栏的提示文字。 | 
| searchingText | String | 搜索时显示的文字,默认为“正在搜索…”。 | 
| proxyBaseUrl | String | 用于 Google Maps API 调用的代理基础 URL。 | 
| httpClient | Client | 用于 Google Maps API 调用的 HTTP 客户端。 | 
| autoCompleteDebounceInMilliseconds | int | 自动完成输入的防抖计时器,默认为 500 毫秒。 | 
| cameraMoveDebounceInMilliseconds | int | 地图拖动时搜索的防抖计时器,默认为 750 毫秒。 | 
| intialMapType | MapType | Google Maps 的地图类型,默认为普通模式。 | 
| enableMapTypeButton | bool | 是否显示地图类型切换按钮。 | 
| enableMyLocationButton | bool | 是否显示我的位置按钮。 | 
| usePinPointingSearch | bool | 默认为 true,允许用户拖动地图并获取指针指向的位置信息。 | 
| usePlaceDetailSearch | bool | 默认为 false,设置为 true 时,拖动地图搜索将获取更详细的结果,但会增加一次 Place Detail API 请求。 | 
| onAutoCompleteFailed | Callback(String) | 自动完成搜索失败时触发的回调。 | 
| onGeocodingSearchFailed | Callback(String) | 拖动地图搜索失败时触发的回调。 | 
| onMapCreated | MapCreatedCallback | 地图创建完成后返回控制器。 | 
| selectedPlaceWidgetBuilder | WidgetBuilder | 下面部分有详细介绍。 | 
| pinBuilder | WidgetBuilder | 下面部分有详细介绍。 | 
| autocompleteOffset | num | 服务匹配预测的最后一个字符的位置。 | 
| autocompleteRadius | num | 返回地点结果的距离范围(单位:米)。 | 
| autocompleteLanguage | String | 结果的语言代码,详见 Google Maps 语言支持。 | 
| autocompleteComponents | List<Components> | 限制搜索结果的地点分组。最多可以按 5 个国家进行过滤。 | 
| autocompleteTypes | List<String> | 返回地点结果的类型。详见 Place Types 文档。 | 
| strictbounds | bool | 返回仅限于指定区域内的地点。 | 
| region | String | 地区代码,指定为 ccTLD(国家顶级域名)的两位字符值。 | 
| selectInitialPosition | bool | 是否在初始地图加载时显示选定地点。默认为 false。 | 
| resizeToAvoidBottomInset | bool | 引用 Scaffold 的 resizeToAvoidBottomInset 属性。 | 
| initialSearchString | String | 自动完成搜索的初始搜索字符串。 | 
| searchForInitialValue | bool | 是否在启动时自动搜索初始值。 | 
| forceAndroidLocationManager | bool | 在 Android 设备上可以设置为 true,强制使用 LocationManager 来确定位置,而不是 FusedLocationProviderClient。 | 
| myLocationButtonCooldown | int | myLocationButton 的冷却时间,单位为秒,默认为 10 秒。 | 
| forceSearchOnZoomChanged | bool | 是否允许在缩放更改时进行地点搜索。默认为 false。 | 
| automaticallyImplyAppBarLeading | bool | 默认情况下顶部有一个返回按钮。设置为 false 将移除返回按钮。 | 
| autocompleteOnTrailingWhitespace | bool | 是否允许在搜索末尾空格时运行自动完成。默认为 false。 | 
更多关于自动完成搜索的信息可以参考 Google Places 自动完成文档。
自定义选择地点的可视化效果
默认情况下,当用户通过自动完成搜索或拖动地图选择地点时,信息会显示在屏幕底部(FloatingCard)。
如果你不喜欢这种 UI/UX,可以通过 selectedPlaceWidgetBuilder 覆盖默认实现。可以复用 FloatingCard 或者根据需求构建全新的小部件。它堆叠在地图之上,因此可能需要使用 Positioned 小部件。
注意:使用此自定义选项不会触发 [onPlacePicked] 回调,因为它会覆盖默认的“选择这里”按钮。
PlacePicker(
  apiKey: APIKeys.apiKey,
  onPlacePicked: (result) {
    print(result.address);
    Navigator.of(context).pop();
  },
  initialPosition: HomePage.kInitialPosition,
  useCurrentLocation: true,
  selectedPlaceWidgetBuilder: (
    BuildContext context,
    PickResult selectedPlace,
    SearchingState state,
    bool isSearchBarFocused,
  ) {
    return isSearchBarFocused
        ? Container()
        // 可以复用 FloatingCard 或自定义小部件。
        : FloatingCard(
            bottomPosition: 0.0, // 使用 MediaQuery.of(context) 会导致重建。详见文档。
            leftPosition: 0.0,
            rightPosition: 0.0,
            width: 500,
            borderRadius: BorderRadius.circular(12.0),
            child: state == SearchingState.Searching
                ? Center(child: CircularProgressIndicator())
                : RaisedButton(
                    onPressed: () {
                      print("do something with [selectedPlace] data");
                    },
                  ),
          );
  },
),
参数说明:
| 参数名称 | 类型 | 描述 | 
|---|---|---|
| context | BuildContext | Flutter 的构建上下文值。 | 
| selectedPlace | PickResult | 用户选择地点的结果数据。 | 
| state | SearchingState | 搜索操作的状态。(空闲、搜索中) | 
| isSearchBarFocused | bool | 搜索栏是否当前聚焦,键盘是否显示。 | 
自定义地标
默认情况下,地标图标具有简单的拖动动画。
你可以通过 pinBuilder 创建自己的地标小部件。
PlacePicker(
  apiKey: APIKeys.apiKey,
  pinBuilder: (BuildContext context, PinState state) {
    if (state == PinState.Idle) {
      return Icon(Icons.favorite_border);
    } else {
      return AnimatedIcon(...);
    }
  },
),
参数说明:
| 参数名称 | 类型 | 描述 | 
|---|---|---|
| context | BuildContext | Flutter 的构建上下文值。 | 
| state | PinState | 地标状态。(准备中、加载中、拖动中) | 
更改默认 FloatingCard 的颜色
虽然你可以构建自己的预测小部件,但仍然可以通过 themeData 更改默认小部件的样式:
// 浅色主题
final ThemeData lightTheme = ThemeData.light().copyWith(
  // FloatingCard 的背景颜色
  cardColor: Colors.white,
  buttonTheme: ButtonThemeData(
    // “选择这里”按钮的颜色
    buttonColor: Colors.black,
    textTheme: ButtonTextTheme.primary,
  ),
);
// 深色主题
final ThemeData darkTheme = ThemeData.dark().copyWith(
  // FloatingCard 的背景颜色
  cardColor: Colors.grey,
  buttonTheme: ButtonThemeData(
    // “选择这里”按钮的颜色
    buttonColor: Colors.yellow,
    textTheme: ButtonTextTheme.primary,
  ),
);
更多关于Flutter地点选择器插件google_places_picker_advance的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地点选择器插件google_places_picker_advance的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
google_places_picker_advance 是一个用于 Flutter 的插件,它提供了一个高级的地点选择器,允许用户通过 Google Places API 选择地点。这个插件可以帮助你轻松地集成 Google Places 功能到你的 Flutter 应用中,让用户能够搜索并选择地点。
以下是如何使用 google_places_picker_advance 插件的步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml 文件中添加 google_places_picker_advance 插件的依赖:
dependencies:
  flutter:
    sdk: flutter
  google_places_picker_advance: ^1.0.0  # 请检查最新版本
然后运行 flutter pub get 来安装依赖。
2. 获取 Google Places API 密钥
在使用这个插件之前,你需要在 Google Cloud Platform 上启用 Google Places API,并获取一个 API 密钥。
- 访问 Google Cloud Console.
 - 创建一个新项目或选择一个现有项目。
 - 导航到 “API 和服务” > “启用 API 和服务”。
 - 搜索并启用 “Places API”。
 - 在 “API 和服务” > “凭据” 中创建一个 API 密钥。
 
3. 配置 API 密钥
在你的 Flutter 项目中,你需要在 Android 和 iOS 平台上配置 API 密钥。
Android
在 android/app/src/main/AndroidManifest.xml 文件中添加以下内容:
<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="YOUR_API_KEY"/>
iOS
在 ios/Runner/AppDelegate.swift 文件中添加以下内容:
import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("YOUR_API_KEY")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
4. 使用插件
在你的 Flutter 代码中,你可以使用 GooglePlacesPickerAdvance 来启动地点选择器。
import 'package:flutter/material.dart';
import 'package:google_places_picker_advance/google_places_picker_advance.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}
class HomeScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Google Places Picker'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // 启动地点选择器
            PlacePickerResult result = await GooglePlacesPickerAdvance.showPlacePicker(
              apiKey: 'YOUR_API_KEY',
            );
            if (result != null) {
              print('Selected Place: ${result.name}');
              print('Address: ${result.formattedAddress}');
              print('Latitude: ${result.geometry.location.lat}');
              print('Longitude: ${result.geometry.location.lng}');
            } else {
              print('No place selected');
            }
          },
          child: Text('Pick a Place'),
        ),
      ),
    );
  }
}
        
      
            
            
            

