[译]Flutter地图选择器插件map_launcher

930 阅读3分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。

本文翻译自pub: map_launcher | Flutter Package (flutter-io.cn)

译时版本: map_launcher 2.1.2


Map Launcher

Map Launcher 是用于发现设备上安装的可用地图应用的插件,然后带着标记启动它们或者展示方位。

标记导航
Marker.gifNavigation.gif

当前支持的地图应用:

image.png Google Maps

image.png Apple Maps (仅iOS)

image.png Google Maps GO (仅Android)

image.png 百度地图

image.png Amap (高德地图)

image.png Waze

image.png Yandex Maps

image.png Yandex Navigator

image.png Citymapper

image.png Maps.me

image.png OsmAnd

image.png OsmAnd+ (仅Android)

image.png 2GIS

image.png 腾讯 (QQ地图)

image.png HERE WeGo

v1.1.3的破坏性改动

由于 Android 11 的改动,如果编译失败的话,可能需要调整一下 gradle 版本。 可以在这里找到解决方案。

迁移到 v1

破坏性改动: map_launcher 不再依赖 flutter_svg ,这意味着如果想要使用图像的话,需要在工程中添加 flutter_svg 。

这会允许你使用任何版本的 flutter_svg ,它已经修复了一堆 issue,如 #45 、 #40 、等相关的 issue 。

现在 AvailableMapicon 属性返回 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 

显示标记

选项类型必需默认
mapTypeMapType-
coordsCoords(lat, long)-
titleString''
descriptionString''
zoomInt16
extraParamsMap<String, String>{}
地图
mapTypecoordstitledescriptionzoomextraParams
.google仅iOS,看下下面的已知 issue
.apple
.googleGo
.amap仅Android
.baidu
.waze
.yandexMaps
.yandexNavi
.citymapper✓ 不支持标记,而是显示方向
.mapswithme
.osmand仅iOS
.osmandplus仅iOS
.doubleGis✓ Android 不支持标记,而是显示方向
.tencent
.here

显示方向

选项类型必需默认
mapTypeMapType-
destinationCoords(lat, long)-
destinationTitleString'Destination'
originCoords(lat, long)当前位置
originTitleString'Origin'
directionsModeDirectionsMode.driving
waypointsList<Coords(lat, long)>null
extraParamsMap<String, String>{}
地图
mapTypedestinationdestinationTitleoriginoriginTitledirectionsModewaypointsextraParams
.google✓ (iOS 升级到8,Android上不受限?)
.apple
.googleGo
.amap
.baidu
.waze总是使用当前位置
.yandexMaps
.yandexNavi
.citymapper
.mapswithme仅显示标记
.osmand仅iOS总是使用当前位置
.osmandplus仅iOS总是使用当前位置
.doubleGis
.tencent
.here

附加参数

可以向一些地图应用传递查询参数如 api key 等,使用 extraParams 选项。

这里有一些地图应用已知的参数:

mapTypeextraParams
.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。