Flutter地图集成插件flutter_google_maps的使用
Flutter地图集成插件flutter_google_maps的使用
简介
flutter_google_maps 是一个用于在 iOS、Android 和 Web 应用程序中集成 Google 地图的 Flutter 插件。它是 google_maps_flutter(移动端)和 google_maps(Web)的封装。
开始使用
获取 API 密钥
- 访问 Google Cloud Console 获取 API 密钥。
- 启用 Google Maps SDK:
- 选择项目。
- 在导航菜单中选择“Google Maps”。
- 启用“Maps SDK for Android”或“Maps SDK for iOS”。
Web 配置
<body>
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY"></script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
Android 配置
在 android/app/src/main/AndroidManifest.xml 中添加以下内容:
<manifest ...
<application ...
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR KEY HERE"/>
iOS 配置
Objective-C
在 ios/Runner/AppDelegate.m 中添加以下内容:
#import "AppDelegate.h"
#import "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 中添加以下内容:
import UIKit
import Flutter
import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR KEY HERE")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
同时,在 Info.plist 中添加以下键值对:
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
集成 GoogleMap 小部件
初始化插件
在 main.dart 中初始化插件:
void main() {
GoogleMap.init('API_KEY'); // 替换为你的 API 密钥
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
添加 GoogleMap 小部件
import 'package:flutter/material.dart';
import 'package:flutter_google_maps/flutter_google_maps.dart';
...
GlobalKey<GoogleMapStateBase> _key = GlobalKey<GoogleMapStateBase>();
@override
Widget build(BuildContext context) => GoogleMap(
key: _key,
);
...
示例代码
以下是完整的示例代码,展示如何配置和使用 flutter_google_maps 插件:
// Copyright (c) 2020, the MarchDev Toolkit project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_google_maps/flutter_google_maps.dart';
void main() {
GoogleMap.init('API_KEY'); // 替换为你的 API 密钥
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Google Map Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final _key = GlobalKey<GoogleMapStateBase>();
bool _polygonAdded = false;
bool _darkMapStyle = false;
String _mapStyle;
List<Widget> _buildClearButtons() => [
RaisedButton.icon(
color: Colors.red,
textColor: Colors.white,
icon: Icon(Icons.bubble_chart),
label: Text('CLEAR POLYGONS'),
onPressed: () {
GoogleMap.of(_key).clearPolygons();
setState(() => _polygonAdded = false);
},
),
const SizedBox(width: 16),
RaisedButton.icon(
color: Colors.red,
textColor: Colors.white,
icon: Icon(Icons.pin_drop),
label: Text('CLEAR MARKERS'),
onPressed: () {
GoogleMap.of(_key).clearMarkers();
},
),
const SizedBox(width: 16),
RaisedButton.icon(
color: Colors.red,
textColor: Colors.white,
icon: Icon(Icons.directions),
label: Text('CLEAR DIRECTIONS'),
onPressed: () {
GoogleMap.of(_key).clearDirections();
},
),
];
List<Widget> _buildAddButtons() => [
FloatingActionButton(
child: Icon(_polygonAdded ? Icons.edit : Icons.bubble_chart),
backgroundColor: _polygonAdded ? Colors.orange : null,
onPressed: () {
if (!_polygonAdded) {
GoogleMap.of(_key).addPolygon(
'1',
polygon,
onTap: (polygonId) async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text(
'This dialog was opened by tapping on the polygon!\n'
'Polygon ID is $polygonId',
),
actions: <Widget>[
FlatButton(
onPressed: Navigator.of(context).pop,
child: Text('CLOSE'),
),
],
),
);
},
);
} else {
GoogleMap.of(_key).editPolygon(
'1',
polygon,
fillColor: Colors.purple,
strokeColor: Colors.purple,
);
}
setState(() => _polygonAdded = true);
},
),
const SizedBox(width: 16),
FloatingActionButton(
child: Icon(Icons.pin_drop),
onPressed: () {
GoogleMap.of(_key).addMarkerRaw(
GeoCoord(33.875513, -117.550257),
info: 'test info',
onInfoWindowTap: () async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text(
'This dialog was opened by tapping on the InfoWindow!'),
actions: <Widget>[
FlatButton(
onPressed: Navigator.of(context).pop,
child: Text('CLOSE'),
),
],
),
);
},
);
GoogleMap.of(_key).addMarkerRaw(
GeoCoord(33.775513, -117.450257),
icon: 'assets/images/map-marker-warehouse.png',
info: contentString,
);
},
),
const SizedBox(width: 16),
FloatingActionButton(
child: Icon(Icons.directions),
onPressed: () {
GoogleMap.of(_key).addDirection(
'San Francisco, CA',
'San Jose, CA',
startLabel: '1',
startInfo: 'San Francisco, CA',
endIcon: 'assets/images/map-marker-warehouse.png',
endInfo: 'San Jose, CA',
);
},
),
];
@override
Widget build(BuildContext context) => Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text('Google Map'),
),
body: Stack(
children: <Widget>[
Positioned.fill(
child: GoogleMap(
key: _key,
markers: {
Marker(
GeoCoord(34.0469058, -118.3503948),
),
},
initialZoom: 12,
initialPosition:
GeoCoord(34.0469058, -118.3503948), // Los Angeles, CA
mapType: MapType.roadmap,
mapStyle: _mapStyle,
interactive: true,
onTap: (coord) =>
_scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(coord?.toString()),
duration: const Duration(seconds: 2),
)),
mobilePreferences: const MobileMapPreferences(
trafficEnabled: true,
zoomControlsEnabled: false,
),
webPreferences: WebMapPreferences(
fullscreenControl: true,
zoomControl: true,
),
),
),
Positioned(
top: 16,
left: 16,
child: FloatingActionButton(
child: Icon(Icons.person_pin_circle),
onPressed: () {
final bounds = GeoCoordBounds(
northeast: GeoCoord(34.021307, -117.432317),
southwest: GeoCoord(33.835745, -117.712785),
);
GoogleMap.of(_key).moveCameraBounds(bounds);
GoogleMap.of(_key).addMarkerRaw(
GeoCoord(
(bounds.northeast.latitude + bounds.southwest.latitude) / 2,
(bounds.northeast.longitude + bounds.southwest.longitude) / 2,
),
onTap: (markerId) async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text(
'This dialog was opened by tapping on the marker!\n'
'Marker ID is $markerId',
),
actions: <Widget>[
FlatButton(
onPressed: Navigator.of(context).pop,
child: Text('CLOSE'),
),
],
),
);
},
);
},
),
),
Positioned(
top: 16,
right: kIsWeb ? 60 : 16,
child: FloatingActionButton(
onPressed: () {
if (_darkMapStyle) {
GoogleMap.of(_key).changeMapStyle(null);
_mapStyle = null;
} else {
GoogleMap.of(_key).changeMapStyle(darkMapStyle);
_mapStyle = darkMapStyle;
}
setState(() => _darkMapStyle = !_darkMapStyle);
},
backgroundColor: _darkMapStyle ? Colors.black : Colors.white,
child: Icon(
_darkMapStyle ? Icons.wb_sunny : Icons.brightness_3,
color: _darkMapStyle ? Colors.white : Colors.black,
),
),
),
Positioned(
left: 16,
right: kIsWeb ? 60 : 16,
bottom: 16,
child: Row(
children: <Widget>[
LayoutBuilder(
builder: (context, constraints) =>
constraints.maxWidth < 1000
? Row(children: _buildClearButtons())
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _buildClearButtons(),
),
),
Spacer(),
..._buildAddButtons(),
],
),
),
],
),
);
}
const darkMapStyle = r'''
[
{
"elementType": "geometry",
"stylers": [
{
"color": "#212121"
}
]
},
{
"elementType": "labels.icon",
"stylers": [
{
"visibility": "off"
}
]
},
{
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#757575"
}
]
},
{
"elementType": "labels.text.stroke",
"stylers": [
{
"color": "#212121"
}
]
},
...
];
''';
const contentString = r'''
<div id="content">
<div id="siteNotice"></div>
<h1 id="firstHeading" class="firstHeading">Uluru</h1>
<div id="bodyContent">
<p>
<b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large
sandstone rock formation in the southern part of the
Northern Territory, central Australia. It lies 335 km (208 mi)
south west of the nearest large town, Alice Springs; 450 km
(280 mi) by road. Kata Tjuta and Uluru are the two major
features of the Uluru - Kata Tjuta National Park. Uluru is
sacred to the Pitjantjatjara and Yankunytjatjara, the
Aboriginal people of the area. It has many springs, waterholes,
rock caves and ancient paintings. Uluru is listed as a World
Heritage Site.
</p>
<p>
Attribution: Uluru,
<a href="http://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">
http://en.wikipedia.org/w/index.php?title=Uluru
</a>
(last visited June 22, 2009).
</p>
</div>
</div>
''';
const polygon = [
GeoCoord(32.707868, -117.191018),
GeoCoord(32.705645, -117.191096),
GeoCoord(32.697756, -117.166664),
GeoCoord(32.686486, -117.163206),
GeoCoord(32.675876, -117.169452),
GeoCoord(32.674726, -117.165233),
GeoCoord(32.679833, -117.158487),
GeoCoord(32.677571, -117.153893),
GeoCoord(32.671987, -117.160079),
GeoCoord(32.667547, -117.160477),
GeoCoord(32.654748, -117.147579),
GeoCoord(32.651933, -117.150312),
GeoCoord(32.649676, -117.144334),
GeoCoord(32.631665, -117.138201),
GeoCoord(32.632033, -117.132249),
GeoCoord(32.630156, -117.137234),
GeoCoord(32.628072, -117.136479),
GeoCoord(32.630315, -117.131443),
GeoCoord(32.625930, -117.135312),
GeoCoord(32.623754, -117.131664),
GeoCoord(32.627465, -117.130883),
GeoCoord(32.622598, -117.128791),
GeoCoord(32.622622, -117.133183),
GeoCoord(32.618690, -117.133634),
GeoCoord(32.618980, -117.128403),
GeoCoord(32.609847, -117.132502),
GeoCoord(32.604198, -117.125333),
GeoCoord(32.588260, -117.122032),
GeoCoord(32.591164, -117.116851),
GeoCoord(32.587601, -117.105968),
GeoCoord(32.583792, -117.104434),
GeoCoord(32.570566, -117.101382),
GeoCoord(32.569256, -117.122378),
GeoCoord(32.560825, -117.122903),
GeoCoord(32.557753, -117.131040),
GeoCoord(32.542737, -117.124883),
GeoCoord(32.534156, -117.126062),
GeoCoord(32.563255, -117.134963),
GeoCoord(32.584055, -117.134263),
GeoCoord(32.619405, -117.140001),
GeoCoord(32.655293, -117.157349),
GeoCoord(32.669944, -117.169624),
GeoCoord(32.682710, -117.189445),
GeoCoord(32.685297, -117.208773),
GeoCoord(32.679814, -117.224882),
GeoCoord(32.697212, -117.227058),
GeoCoord(32.707701, -117.219816),
GeoCoord(32.711931, -117.214107),
GeoCoord(32.715026, -117.196521),
GeoCoord(32.713053, -117.189703),
GeoCoord(32.707868, -117.191018),
];
属性说明
GoogleMap 小部件支持的属性
| 属性名称 | 类型 | 描述 |
|---|---|---|
| initialPosition | GeoCoord | 地图初始中心位置 |
| initialZoom | double | 初始缩放级别 |
| mapType | MapType | 地图类型(普通、卫星、地形等) |
| minZoom | double | 最小缩放级别 |
| maxZoom | double | 最大缩放级别 |
| mapStyle | String | 地图样式 |
| mobilePreferences | MobileMapPreferences | 移动端地图偏好设置 |
| webPreferences | WebMapPreferences | Web 端地图偏好设置 |
| interactive | bool | 是否允许交互 |
| onTap | ValueChanged | 地图点击事件 |
| onLongPress | ValueChanged | 地图长按事件 |
| markers | Set | 地图标记 |
MapType 枚举
| 值 | 描述 |
|---|---|
| none | 不显示地图瓦片 |
| roadmap | 普通瓦片(交通和标签,轻微地形信息) |
| satellite | 卫星影像瓦片(航拍照片) |
| terrain | 地形瓦片(指示地形类型和高度) |
| hybrid | 混合瓦片(卫星图像与一些标签/叠加层) |
MobileMapPreferences 支持的属性
| 属性名称 | 类型 | 描述 |
|---|---|---|
| compassEnabled | bool | 是否显示指南针 |
| mapToolbarEnabled | bool | 是否显示工具栏(仅限 Android) |
| myLocationEnabled | bool | 是否显示“我的位置”图层 |
| myLocationButtonEnabled | bool | 是否启用“我的位置”按钮 |
| indoorViewEnabled | bool | 是否启用室内视图 |
| trafficEnabled | bool | 是否启用交通图层 |
| buildingsEnabled | bool | 是否显示可用的 3D 建筑物 |
| padding | EdgeInsets | 地图细节的填充 |
| rotateGesturesEnabled | bool | 是否响应旋转手势 |
| scrollGesturesEnabled | bool | 是否响应滚动手势 |
| zoomGesturesEnabled | bool | 是否响应缩放手势 |
| tiltGesturesEnabled | bool | 是否响应倾斜手势 |
WebMapPreferences 支持的属性
| 属性名称 | 类型 | 描述 |
|---|---|---|
| streetViewControl | bool | 是否启用街景控件 |
| fullscreenControl | bool | 是否启用全屏控件 |
| mapTypeControl | bool | 是否启用地图类型控件 |
| scrollwheel | bool | 是否启用滚轮缩放 |
| panControl | bool | 是否启用平移控件 |
| overviewMapControl | bool | 是否启用概览地图控件 |
| rotateControl | bool | 是否启用旋转控件 |
| scaleControl | bool | 是否启用比例尺控件 |
| zoomControl | bool | 是否启用缩放控件 |
| dragGestures | bool | 是否启用拖动手势 |
与 GoogleMap 交互
使用静态方法 of
示例:移动相机到新边界
void moveCameraBounds(
GeoCoordBounds newBounds, {
double padding = 0,
bool animated = true,
bool waitUntilReady = true,
});
示例:移动相机到新坐标
void moveCamera(
GeoCoord latLng, {
bool animated = true,
bool waitUntilReady = true,
double zoom,
});
示例:获取地图中心坐标
FutureOr<GeoCoord> get center;
示例:改变地图样式
void changeMapStyle(String mapStyle);
示例:添加标记
void addMarkerRaw(
GeoCoord position, {
String label,
String icon,
String info,
ValueChanged<String> onTap,
VOidCallback onInfoWindowTap,
});
示例:删除所有标记
void clearMarkers();
更多关于Flutter地图集成插件flutter_google_maps的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地图集成插件flutter_google_maps的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_google_maps 是一个用于在 Flutter 应用中集成 Google 地图的插件。它允许你在应用中显示地图、添加标记、处理用户交互等。以下是如何使用 flutter_google_maps 插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml 文件中添加 flutter_google_maps 插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_google_maps: ^latest_version
然后运行 flutter pub get 来获取依赖。
2. 获取 Google Maps API 密钥
要使用 Google 地图,你需要一个 Google Maps API 密钥。你可以通过以下步骤获取:
- 访问 Google Cloud Console。
- 创建一个新项目或选择现有项目。
- 启用
Maps SDK for Android和Maps SDK for iOS。 - 在
API 和服务->凭据中创建一个 API 密钥。
3. 配置 Android 和 iOS 项目
Android
在 android/app/src/main/AndroidManifest.xml 文件中添加以下代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_ANDROID_API_KEY"/>
</application>
</manifest>
iOS
在 ios/Runner/AppDelegate.swift 文件中添加以下代码:
import UIKit
import Flutter
import GoogleMaps
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR_IOS_API_KEY")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
4. 使用 GoogleMap 组件
在你的 Flutter 应用中使用 GoogleMap 组件来显示地图。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:flutter_google_maps/flutter_google_maps.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Google Maps Example'),
),
body: GoogleMap(
initialPosition: GeoCoord(37.7749, -122.4194), // 初始位置(旧金山)
mapType: MapType.normal,
markers: {
Marker(
markerId: MarkerId('marker_1'),
position: GeoCoord(37.7749, -122.4194),
infoWindow: InfoWindow(title: 'San Francisco'),
),
},
onMapCreated: (GoogleMapController controller) {
// 地图创建完成后的回调
},
),
),
);
}
}

