Flutter 中Google 地图组件包 `google_maps_flutter

我来详细介绍 Flutter 中常用的 Google 地图组件包 google_maps_flutter

概述

google_maps_flutter 是 Flutter 官方维护的 Google Maps 插件,允许在 Flutter 应用中嵌入 Google 地图。

安装配置

1. 添加依赖

yaml 复制代码
dependencies:
google_maps_flutter: ^2.4.0

2. 平台配置

Android:

xml 复制代码
<!-- android/app/src/main/AndroidManifest.xml -->
<manifest>
<application>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_ANDROID_API_KEY"/>
</application>
</manifest>

iOS:

swift 复制代码
// ios/Runner/AppDelegate.swift
import GoogleMaps

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR_IOS_API_KEY")
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

基础用法

1. 显示地图

dart 复制代码
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class SimpleMap extends StatefulWidget {
@override
_SimpleMapState createState() => _SimpleMapState();
}

class _SimpleMapState extends State<SimpleMap> {
late GoogleMapController mapController;

final LatLng _center = const LatLng(31.2304, 121.4737); // 上海坐标

void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Google Maps')),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 12.0,
),
// 启用用户位置
myLocationEnabled: true,
myLocationButtonEnabled: true,
// 手势支持
zoomControlsEnabled: true,
rotateGesturesEnabled: true,
scrollGesturesEnabled: true,
tiltGesturesEnabled: true,
zoomGesturesEnabled: true,
),
);
}
}

2. 添加标记

dart 复制代码
Set<Marker> _markers = {};

@override
void initState() {
super.initState();

// 添加标记
_markers.add(
Marker(
markerId: MarkerId('marker_1'),
position: LatLng(31.2304, 121.4737),
infoWindow: InfoWindow(
title: '上海',
snippet: '中国最大城市',
),
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueRed,
),
onTap: () {
print('标记被点击');
},
),
);

// 添加自定义图标标记
_markers.add(
Marker(
markerId: MarkerId('custom_marker'),
position: LatLng(31.2204, 121.4837),
icon: BitmapDescriptor.fromBytes(customIconBytes),
anchor: Offset(0.5, 0.5), // 图标锚点
),
);
}

GoogleMap(
markers: _markers,
// ... 其他配置
)

3. 绘制图形

dart 复制代码
Set<Polygon> _polygons = {};
Set<Polyline> _polylines = {};
Set<Circle> _circles = {};

void _addShapes() {
// 多边形
_polygons.add(
Polygon(
polygonId: PolygonId('polygon_1'),
points: [
LatLng(31.2304, 121.4737),
LatLng(31.2404, 121.4837),
LatLng(31.2204, 121.4937),
],
strokeWidth: 2,
strokeColor: Colors.blue,
fillColor: Colors.blue.withOpacity(0.15),
),
);

// 折线
_polylines.add(
Polyline(
polylineId: PolylineId('polyline_1'),
points: [
LatLng(31.2304, 121.4737),
LatLng(31.2404, 121.4837),
],
color: Colors.red,
width: 3,
geodesic: true, // 大圆线
),
);

// 圆形
_circles.add(
Circle(
circleId: CircleId('circle_1'),
center: LatLng(31.2304, 121.4737),
radius: 500, // 米
strokeWidth: 2,
strokeColor: Colors.green,
fillColor: Colors.green.withOpacity(0.15),
),
);
}

GoogleMap(
polygons: _polygons,
polylines: _polylines,
circles: _circles,
)

4. 地图控制

dart 复制代码
// 移动到指定位置
void _moveCamera() {
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(39.9042, 116.4074), // 北京
zoom: 14.0,
bearing: 45, // 旋转角度
tilt: 30,// 倾斜角度
),
),
);
}

// 移动到边界
void _moveToBounds() {
mapController.animateCamera(
CameraUpdate.newLatLngBounds(
LatLngBounds(
southwest: LatLng(31.2204, 121.4637),
northeast: LatLng(31.2404, 121.4837),
),
padding: 50, // 边距
),
);
}

// 获取当前可视区域
void _getVisibleRegion() async {
LatLngBounds bounds = await mapController.getVisibleRegion();
print('可视区域: ${bounds.southwest} - ${bounds.northeast}');
}

5. 事件监听

dart 复制代码
GoogleMap(
onMapCreated: (controller) {
mapController = controller;
},
onCameraMove: (CameraPosition position) {
print('相机移动: ${position.target}');
},
onCameraIdle: () {
print('相机停止移动');
},
onTap: (LatLng position) {
print('地图点击: $position');
},
onLongPress: (LatLng position) {
print('地图长按: $position');
},
)

6. 自定义地图样式

dart 复制代码
void _setMapStyle() async {
String style = await DefaultAssetBundle.of(context)
.loadString('assets/map_style.json');
mapController.setMapStyle(style);
}

// map_style.json 示例
[
{
"featureType": "all",
"elementType": "geometry",
"stylers": [
{"color": "#242f3e"}
]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [
{"color": "#515c6d"}
]
}
]

高级功能

1. 标记聚类

使用第三方库 flutter_map_marker_cluster

dart 复制代码
dependencies:
flutter_map_marker_cluster: ^0.3.0

2. 离线地图

dart 复制代码
// 设置离线区域
void _setOfflineRegion() {
mapController.setOfflineTileData(
LatLngBounds(
southwest: LatLng(31.2204, 121.4637),
northeast: LatLng(31.2404, 121.4837),
),
minZoom: 10,
maxZoom: 15,
);
}

3. 性能优化

dart 复制代码
class OptimizedMap extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(31.2304, 121.4737),
zoom: 12,
),
// 优化选项
minMaxZoomPreference: MinMaxZoomPreference(8, 18),
cameraTargetBounds: CameraTargetBounds.unbounded,
// 轻量模式
liteModeEnabled: false,
// 纹理层
textureRenderingEnabled: false,
// 标记批处理
markersClusteringEnabled: true,
);
}
}

完整示例

dart 复制代码
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class AdvancedMapPage extends StatefulWidget {
@override
_AdvancedMapPageState createState() => _AdvancedMapPageState();
}

class _AdvancedMapPageState extends State<AdvancedMapPage> {
late GoogleMapController _controller;
Set<Marker> _markers = {};
Set<Polyline> _polylines = {};

final LatLng _initialPosition = LatLng(31.2304, 121.4737);

@override
void initState() {
super.initState();
_setupMarkers();
_setupPolylines();
}

void _setupMarkers() {
_markers.addAll([
Marker(
markerId: MarkerId('marker1'),
position: LatLng(31.2304, 121.4737),
infoWindow: InfoWindow(title: '位置1'),
),
Marker(
markerId: MarkerId('marker2'),
position: LatLng(31.2404, 121.4837),
infoWindow: InfoWindow(title: '位置2'),
),
]);
}

void _setupPolylines() {
_polylines.add(
Polyline(
polylineId: PolylineId('route'),
points: [
LatLng(31.2304, 121.4737),
LatLng(31.2404, 121.4837),
],
color: Colors.blue,
width: 4,
),
);
}

void _zoomIn() {
_controller.animateCamera(CameraUpdate.zoomIn());
}

void _zoomOut() {
_controller.animateCamera(CameraUpdate.zoomOut());
}

void _goToMyLocation() async {
// 实际应用中需要获取用户当前位置
_controller.animateCamera(
CameraUpdate.newLatLng(_initialPosition),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('高级地图示例'),
actions: [
IconButton(
icon: Icon(Icons.my_location),
onPressed: _goToMyLocation,
),
],
),
body: Stack(
children: [
GoogleMap(
onMapCreated: (controller) => _controller = controller,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 12,
),
markers: _markers,
polylines: _polylines,
myLocationEnabled: true,
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
),
Positioned(
right: 16,
bottom: 100,
child: Column(
children: [
FloatingActionButton(
onPressed: _zoomIn,
child: Icon(Icons.add),
mini: true,
),
SizedBox(height: 8),
FloatingActionButton(
onPressed: _zoomOut,
child: Icon(Icons.remove),
mini: true,
),
],
),
),
],
),
);
}
}

注意事项

  1. API 密钥安全:不要将 API 密钥硬编码在代码中
  2. 计费:Google Maps 有使用限制和计费标准
  3. 权限:确保在 Android 和 iOS 中正确配置位置权限
  4. 网络:地图需要网络连接加载图块
  5. 性能:大量标记或复杂图形可能影响性能

替代方案

如果 Google Maps 不可用,可以考虑:

  • mapbox_gl:Mapbox 地图
  • leaflet_flutter:Leaflet 地图
  • amap_flutter_map:高德地图(中国)

这个插件提供了丰富的功能,适合大多数地图应用需求。记得根据实际功能选择合适的配置,并注意平台特定的设置。

相关推荐
麒麟ZHAO4 小时前
鸿蒙flutter第三方库适配 - 动态表单
flutter·华为·harmonyos
见山是山-见水是水5 小时前
鸿蒙flutter第三方库适配 - 页面转场应用
flutter·华为·harmonyos
恋猫de小郭5 小时前
Flutter PC 多窗口最新进展,底层原生窗口句柄支持已合并
android·前端·flutter
见山是山-见水是水6 小时前
鸿蒙flutter第三方库适配 - 主题切换应用
flutter·华为·harmonyos
牛马1116 小时前
Flutter BoxDecoration boxShadow 完整用法
flutter
见山是山-见水是水7 小时前
鸿蒙flutter第三方库适配 - 多语言应用
flutter·华为·harmonyos
麒麟ZHAO7 小时前
Flutter 框架跨平台鸿蒙开发 - 匿名真心话
flutter·华为·harmonyos
langyuejing7 小时前
Flutter 原生能力集成指南
flutter
麒麟ZHAO7 小时前
鸿蒙flutter第三方库适配 - 新闻阅读应用
flutter·华为·harmonyos