使用一些app的时候,我们会发现他们定位导航的时候,不是在自己app,而是直接跳转到其他的定位导航app,如果不是必须对接app内导航的话,这种策略能大幅度减少生产和运营app的成本
下面就介绍一下,怎么对接的,对接过程中有哪些注意事项吧
设置依赖
核心库 map_launcher,flutter_svg包含了其中的一些logo信息,需要的话可以引入
flutter pub add map_launcher
dependencies:
map_launcher: ^2.4.0
flutter_svg: # only if you want to use icons as they are svgs
ios 端设置 schemes 以便于跳转对应 地图类app
<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>
<string>tomtomgo</string>
</array>
MapLauncher.installedMaps
获取手机内 所有地图类app,以便于跳转(当然前提是三方库支持的 主流地图app ),结果返回的是一个 Future,注意获取方式
//获取手机内安装的所有地图类app
final availableMaps = await MapLauncher.installedMaps;
MapLauncher.isMapAvailable
判断 指定地图app 是否能够是跳转使用,返回的也是 Future,注意调用
if (await MapLauncher.isMapAvailable(MapType.amap) != null) {
//判断是否
}
showMarker
跳转地图app时,立即在指定位置 添加 marker 信息并显示
final coords = Coords(37.759392, 117.5107336);
//从列表选择时,直接使用item即可
map.showMarker(
coords: coords, //目的地定位信息
title: "mark标题",
description: "我给你标记的位置"
);
//如果是跳转指定app,可以使用 MapLauncher 静态(类)方法调用,然后 mapType 参数传入平台即可
MapLauncher.showMarker(
mapType: MapType.amap,
coords: coords,
title: "高德marker标题",
description: "我给你标记的位置",
);
showDirections
与 showMarker 类似,参数略有不同,用的稍多
final coords = Coords(37.759392, 117.5107336);
//从列表选择时,直接使用item即可
map.showDirections(
// origin: coords,//当前位置,不填写就是自身位置
destination: coords, //目的位置
// originTitle: '其实位置标题信息(根据这个搜索)',
// destinationTitle: "目的标题信息", //非必填
directionsMode: DirectionsMode.walking, //默认为.driving可以点进去选择
);
//如果是跳转指定app,可以使用 MapLauncher 静态(类)方法调用,然后 mapType 参数传入平台即可
MapLauncher.showDirections(
mapType: MapType.amap, //选择类型
// origin: coords,//当前位置,不填写就是自身位置
destination: coords, //目的位置
// originTitle: '其实位置标题信息(根据这个搜索)',
// destinationTitle: "目的标题信息",
directionsMode: DirectionsMode.walking, //默认为.driving可以点进去选择
);
话不多说了不多说直接上代码
//以actionSheet的方式打开地图类app选择列表
//然后点击item效果是跳转到指定app后显示marker
openMapsSheetWithMarker() async {
try {
//目的地地址
final coords = Coords(37.759392, 117.5107336);
//获取手机内安装的地图类app
final availableMaps = await MapLauncher.installedMaps;
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Wrap(
//使用 ListTile 平铺布局即可
children: availableMaps.map<Widget>((map) {
return ListTile(
onTap: () {
//天机后
map.showMarker(
coords: coords,
title: "mark标题",
description: "我给你标记的位置"
);
},
title: Text(map.mapName),
leading: SvgPicture.asset(
map.icon,
height: 30.0,
width: 30.0,
),
);
}).toList(),
),
),
);
},
);
} catch (e) {
print(e);
}
}
//以高德的方式显示目的位置marker
openOnGaode() async {
final coords = Coords(37.759392, 117.5107336);
if (await MapLauncher.isMapAvailable(MapType.amap) != null) {
await MapLauncher.showMarker(
mapType: MapType.amap,
coords: coords,
title: "高德marker标题",
description: "我给你标记的位置",
);
}else {
showDialog(
context: context,
builder: (context) {
return const Text("不能打开");
},
);
}
}
//以actionSheet的方式打开地图类app选择列表
//然后点击item效果是跳转到指定app后 显示开始到目的地导航
openMapsSheetWithNavigaiton() async {
try {
final coords = Coords(37.759392, 117.5107336);
final availableMaps = await MapLauncher.installedMaps;
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Wrap(
children: availableMaps.map<Widget>((map) {
return ListTile(
onTap: () {
map.showDirections(
// origin: coords,//当前位置 //不填写就是当前位置
destination: coords, //目的位置
// originTitle: '其实位置标题信息(根据这个搜索)',
// destinationTitle: "目的标题信息",
directionsMode: DirectionsMode.walking, //默认为.driving可以点进去选择
);
},
title: Text(map.mapName),
leading: SvgPicture.asset(
map.icon,
height: 30.0,
width: 30.0,
),
);
}).toList(),
),
),
);
},
);
} catch (e) {
print(e);
}
}
//以高德的方式显示开始到目的地导航
openOnGaodeWithNavigaiton() async {
final coords = Coords(37.759392, 117.5107336);
if (await MapLauncher.isMapAvailable(MapType.amap) != null) {
MapLauncher.showDirections(
mapType: MapType.amap, //选择类型
// origin: coords,//当前位置 //不填写就是当前位置
destination: coords, //目的位置
// originTitle: '其实位置标题信息(根据这个搜索)',
// destinationTitle: "目的标题信息",
directionsMode: DirectionsMode.walking, //默认为.driving可以点进去选择
);
}else {
showDialog(
context: context,
builder: (context) {
return const Text("不能打开");
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('map_launch demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
onPressed: () {
openMapsSheetWithMarker();
},
child: const Text("跳转多平台指定位置"),
),
TextButton(
onPressed: () {
openOnGaode();
},
child: const Text("单独跳转高德指定位置"),
),
TextButton(
onPressed: () {
openMapsSheetWithNavigaiton();
},
child: const Text("跳转多平台导航指定位置"),
),
TextButton(
onPressed: () {
openOnGaodeWithNavigaiton();
},
child: const Text("单独跳转高德导航指定位置"),
),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}