如何在Flutter中使用mapbox_maps_flutter包实现逐向导航?
使用mapbox_maps_flutter实现逐向导航的分步方案
一、前期配置
- 在
pubspec.yaml中添加官方包依赖:dependencies: mapbox_maps_flutter: ^最新版本号 - 配置Mapbox密钥与权限:
- Android:在
AndroidManifest.xml的<application>标签内添加密钥,同时声明位置权限<meta-data android:name="com.mapbox.access_token" android:value="你的Mapbox密钥"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/> - iOS:在
Info.plist中添加密钥与位置权限描述<key>MGLMapboxAccessToken</key> <string>你的Mapbox密钥</string> <key>NSLocationWhenInUseUsageDescription</key> <string>需要获取你的位置以提供导航服务</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>需要在后台获取你的位置以持续提供导航服务</string>
- Android:在
二、核心实现步骤
1. 初始化地图与导航控制器
创建地图组件并初始化导航控制器,用于绑定导航逻辑:
import 'package:flutter/material.dart'; import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; import 'package:permission_handler/permission_handler.dart'; class NavigationScreen extends StatefulWidget { const NavigationScreen({super.key}); @override State<NavigationScreen> createState() => _NavigationScreenState(); } class _NavigationScreenState extends State<NavigationScreen> { late MapboxMap mapboxMap; late NavigationViewController navigationController; // 示例起点与终点坐标 final _origin = Point(coordinates: Position(-73.9857, 40.7484)); final _destination = Point(coordinates: Position(-74.0060, 40.7128)); @override Widget build(BuildContext context) { return Scaffold( body: MapWidget( onMapCreated: (mapboxMap) { this.mapboxMap = mapboxMap; _initNavigationController(); }, navigationOptions: const NavigationOptions( voiceInstructionsEnabled: true, bannerInstructionsEnabled: true, ), ), floatingActionButton: FloatingActionButton( onPressed: _startNavigation, child: const Icon(Icons.navigation), ), ); } void _initNavigationController() async { navigationController = NavigationViewController(); await navigationController.initialize(); // 监听导航进度更新 navigationController.onRouteProgress.listen((progress) { if (progress.currentStep != null) { print("当前导航提示:${progress.currentStep!.instruction}"); } }); } }
2. 权限检查与启动导航
添加权限校验逻辑,请求路线并启动逐向导航:
Future<bool> _checkLocationPermission() async { final permissionStatus = await Permission.locationWhenInUse.request(); if (permissionStatus.isGranted) { return true; } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("需要开启位置权限才能使用导航功能")), ); return false; } } void _startNavigation() async { final hasPermission = await _checkLocationPermission(); if (!hasPermission) return; // 配置路线请求参数(支持驾车/步行/骑行模式) final routeOptions = RouteOptions( profileIdentifier: ProfileIdentifier.DRIVING, coordinates: [_origin.coordinates, _destination.coordinates], ); try { final routeResponse = await navigationController.requestRoutes(routeOptions); if (routeResponse.routes != null && routeResponse.routes!.isNotEmpty) { // 启动导航 await navigationController.startNavigation( routeIndex: 0, navigationOptions: const NavigationOptions( enableRefresh: true, voiceInstructionsEnabled: true, ), ); } } catch (e) { print("路线请求失败:$e"); } }
3. 导航状态控制
可通过导航控制器实现暂停、停止等操作:
// 暂停导航 void _pauseNavigation() async { await navigationController.pauseNavigation(); } // 停止导航 void _stopNavigation() async { await navigationController.stopNavigation(); }
三、关键注意事项
- 确保你的Mapbox账户已开启Navigation API权限,否则会出现路线请求失败的情况
- 禁止同时集成
flutter_mapbox_navigation包,两者底层依赖存在冲突 - 可通过
NavigationOptions自定义导航的语音、横幅提示样式,或修改地图样式适配导航场景
内容的提问来源于stack exchange,提问作者Naqeeb Awan
相关产品推荐
相关产品推荐

