「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
本文翻译自pub: map_launcher | Flutter Package (flutter-io.cn)
译时版本: map_launcher 2.1.2
Map Launcher
Map Launcher 是用于发现设备上安装的可用地图应用的插件,然后带着标记启动它们或者展示方位。
| 标记 | 导航 |
|---|---|
当前支持的地图应用:
Google Maps
Apple Maps (仅iOS)
Google Maps GO (仅Android)
百度地图
Amap (高德地图)
Waze
Yandex Maps
Yandex Navigator
Citymapper
Maps.me
OsmAnd
OsmAnd+ (仅Android)
2GIS
腾讯 (QQ地图)
HERE WeGo
v1.1.3的破坏性改动
由于 Android 11 的改动,如果编译失败的话,可能需要调整一下 gradle 版本。 可以在这里找到解决方案。
迁移到 v1
破坏性改动: map_launcher 不再依赖 flutter_svg ,这意味着如果想要使用图像的话,需要在工程中添加 flutter_svg 。
这会允许你使用任何版本的 flutter_svg ,它已经修复了一堆 issue,如 #45 、 #40 、等相关的 issue 。
现在 AvailableMap 的 icon 属性返回 String 而不是 ImageProvider ,所以要使其都正常使用,需要如下去做:
从
Image(
image: map.icon,
)
改为
import 'package:flutter_svg/flutter_svg.dart';
SvgPicture.asset(
map.icon,
)
开始
添加依赖
dependencies:
map_launcher: ^2.1.2
flutter_svg: # only if you want to use icons as they are svgs
对于 iOS 在 Info.plist 文件中 添加 url schemes
<key>LSApplicationQueriesSchemes</key>
<array>
<string>comgooglemaps</string>
<string>baidumap</string>
<string>iosamap</string>
<string>waze</string>
<string>yandexmaps</string>
<string>yandexnavi</string>
<string>citymapper</string>
<string>mapswithme</string>
<string>osmandmaps</string>
<string>dgis</string>
<string>qqmap</string>
<string>here-location</string>
</array>
用法
列出已安装的地图应用并加载第一个
import 'package:map_launcher/map_launcher.dart';
final availableMaps = await MapLauncher.installedMaps;
print(availableMaps); // [AvailableMap { mapName: Google Maps, mapType: google }, ...]
await availableMaps.first.showMarker(
coords: Coords(37.759392, -122.5107336),
title: "Ocean Beach",
);
检查地图应用是否已安装并加载
import 'package:map_launcher/map_launcher.dart';
if (await MapLauncher.isMapAvailable(MapType.google)) {
await MapLauncher.showMarker(
mapType: MapType.google,
coords: coords,
title: title,
description: description,
);
}
API
显示标记
| 选项 | 类型 | 必需 | 默认 |
|---|---|---|---|
mapType | MapType | 是 | - |
coords | Coords(lat, long) | 是 | - |
title | String | 否 | '' |
description | String | 否 | '' |
zoom | Int | 否 | 16 |
extraParams | Map<String, String> | 否 | {} |
地图
mapType | coords | title | description | zoom | extraParams |
|---|---|---|---|---|---|
.google | ✓ | 仅iOS,看下下面的已知 issue | ✗ | ✓ | ✓ |
.apple | ✓ | ✓ | ✗ | ✗ | ✓ |
.googleGo | ✓ | ✗ | ✗ | ✓ | ✓ |
.amap | ✓ | ✓ | ✓ | 仅Android | ✓ |
.baidu | ✓ | ✓ | ✓ | ✓ | ✓ |
.waze | ✓ | ✗ | ✗ | ✓ | ✓ |
.yandexMaps | ✓ | ✗ | ✗ | ✓ | ✓ |
.yandexNavi | ✓ | ✓ | ✗ | ✓ | ✓ |
.citymapper | ✓ 不支持标记,而是显示方向 | ✓ | ✗ | ✗ | ✓ |
.mapswithme | ✓ | ✓ | ✗ | ✗ | ✓ |
.osmand | ✓ | 仅iOS | ✗ | ✓ | ✓ |
.osmandplus | ✓ | 仅iOS | ✗ | ✓ | ✓ |
.doubleGis | ✓ Android 不支持标记,而是显示方向 | ✗ | ✗ | ✗ | ✓ |
.tencent | ✓ | ✓ | ✗ | ✗ | ✓ |
.here | ✓ | ✓ | ✗ | ✓ | ✓ |
显示方向
| 选项 | 类型 | 必需 | 默认 |
|---|---|---|---|
mapType | MapType | 是 | - |
destination | Coords(lat, long) | 是 | - |
destinationTitle | String | 否 | 'Destination' |
origin | Coords(lat, long) | 否 | 当前位置 |
originTitle | String | 否 | 'Origin' |
directionsMode | DirectionsMode | 否 | .driving |
waypoints | List<Coords(lat, long)> | 否 | null |
extraParams | Map<String, String> | 否 | {} |
地图
mapType | destination | destinationTitle | origin | originTitle | directionsMode | waypoints | extraParams |
|---|---|---|---|---|---|---|---|
.google | ✓ | ✗ | ✓ | ✗ | ✓ | ✓ (iOS 升级到8,Android上不受限?) | ✓ |
.apple | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.googleGo | ✓ | ✗ | ✓ | ✗ | ✓ | ✓ | ✓ |
.amap | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.baidu | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.waze | ✓ | ✗ | 总是使用当前位置 | ✗ | ✗ | ✗ | ✓ |
.yandexMaps | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.yandexNavi | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.citymapper | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.mapswithme | ✓ | ✓ | 仅显示标记 | ✗ | ✗ | ✗ | ✓ |
.osmand | ✓ | 仅iOS | 总是使用当前位置 | ✗ | ✗ | ✗ | ✓ |
.osmandplus | ✓ | 仅iOS | 总是使用当前位置 | ✗ | ✗ | ✗ | ✓ |
.doubleGis | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ |
.tencent | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
.here | ✓ | ✗ | ✓ | ✓ | ✓ | ✗ | ✓ |
附加参数
可以向一些地图应用传递查询参数如 api key 等,使用 extraParams 选项。
这里有一些地图应用已知的参数:
mapType | extraParams |
|---|---|
.tencent | { 'referer': '' } |
.yandexNavi | { 'client': '', 'signature': '' } |
示例
使用 bottom sheet
import 'package:flutter/material.dart';
import 'package:map_launcher/map_launcher.dart';
import 'package:flutter_svg/flutter_svg.dart';
void main() => runApp(MapLauncherDemo());
class MapLauncherDemo extends StatelessWidget {
openMapsSheet(context) async {
try {
final coords = Coords(37.759392, -122.5107336);
final title = "Ocean Beach";
final availableMaps = await MapLauncher.installedMaps;
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Container(
child: Wrap(
children: <Widget>[
for (var map in availableMaps)
ListTile(
onTap: () => map.showMarker(
coords: coords,
title: title,
),
title: Text(map.mapName),
leading: SvgPicture.asset(
map.icon,
height: 30.0,
width: 30.0,
),
),
],
),
),
),
);
},
);
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Map Launcher Demo'),
),
body: Center(child: Builder(
builder: (context) {
return MaterialButton(
onPressed: () => openMapsSheet(context),
child: Text('Show Maps'),
);
},
)),
),
);
}
}
已知 issue
- Google Maps Android 版有一个 bug ,为标记设置标签不起作用。更多信息可查看 Google Issue Tracker
- 在 iOS 上,只从主页删除 Apple Map 有可能会 “删除” 应用,但实际上并没有删除。因为 iOS 上 Apple Maps 总是显示为可用的。 关于此内容的更多信息可阅读 这里 。
贡献
欢迎PR。