如何通过MapboxNavigation对象启动带UI导航并实现OffRouteListener?
你碰到的问题很典型——MapboxNavigation#startNavigation()本身只是启动后台导航计算会话,负责处理路线跟踪、偏离检测这些核心逻辑,但它完全不负责渲染导航UI(比如地图、转向提示、进度条这些视觉元素)。这就是为什么你调用这个方法后看不到任何界面的原因。
下面给你两种可行的解决方案,你可以根据自己的需求选择:
方案1:继续用NavigationLauncher启动默认UI,同时添加监听器
如果你想保留Mapbox官方的默认导航UI(就是之前用NavigationLauncher.startNavigation()启动的那个界面),同时添加OffRouteListener这类监听器,可以这么做:
首先还是用NavigationLauncher启动导航,同时设置回调来监听导航状态:
NavigationLauncherOptions options = NavigationLauncherOptions.builder() .directionsRoute(directionsRoute) .shouldSimulateRoute(false) .build(); NavigationLauncher.startNavigation(MainActivity.this, options, new NavigationLauncher.Callback() { @Override public void onNavigationFinished() { // 导航结束后的清理工作 } @Override public void onNavigationCanceled() { // 导航取消后的处理 } });导航启动后,通过
MapboxNavigationProvider获取全局的导航实例,然后添加监听器:// 建议在导航启动后的合适时机调用,比如在回调里或者延迟一点执行 MapboxNavigation mapboxNavigation = MapboxNavigationProvider.retrieve(); if (mapboxNavigation != null) { // 保存这个监听器实例,方便后续移除 OffRouteListener offRouteListener = location -> { // 这里写偏离路线后的逻辑,比如提示用户、触发重新规划 Log.d("Navigation", "当前已偏离路线,位置:" + location.getLatitude() + ", " + location.getLongitude()); }; mapboxNavigation.addOffRouteListener(offRouteListener); }别忘了在页面销毁时移除监听器并销毁实例,避免内存泄漏:
@Override protected void onDestroy() { super.onDestroy(); MapboxNavigation mapboxNavigation = MapboxNavigationProvider.retrieve(); if (mapboxNavigation != null) { mapboxNavigation.removeOffRouteListener(offRouteListener); mapboxNavigation.onDestroy(); } }
方案2:使用NavigationView自定义导航UI(更灵活)
如果你想完全自定义导航界面,或者需要更直接地控制MapboxNavigation实例,可以把NavigationView嵌入到自己的Activity布局中,替代NavigationLauncher:
先在布局文件里添加NavigationView:
<com.mapbox.navigation.ui.NavigationView android:id="@+id/navigationView" android:layout_width="match_parent" android:layout_height="match_parent" app:mapbox_navigation_view_routing_profile="driving"/>在Activity中初始化并启动导航:
private MapboxNavigation mapboxNavigation; private NavigationView navigationView; private OffRouteListener offRouteListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); navigationView = findViewById(R.id.navigationView); // 获取NavigationView绑定的MapboxNavigation实例 mapboxNavigation = navigationView.retrieveMapboxNavigation(); // 创建并添加偏离路线监听器 offRouteListener = location -> { // 处理偏离逻辑 }; mapboxNavigation.addOffRouteListener(offRouteListener); // 启动导航,NavigationView会自动渲染导航UI mapboxNavigation.startNavigation(directionsRoute); } @Override protected void onDestroy() { super.onDestroy(); if (mapboxNavigation != null) { mapboxNavigation.removeOffRouteListener(offRouteListener); mapboxNavigation.onDestroy(); } navigationView.onDestroy(); }
这种方式的好处是你可以自由定制导航界面的布局和交互,同时直接掌控MapboxNavigation实例,方便添加各种监听器和自定义逻辑。
简单总结:
- 要保留官方默认UI,选方案1最省心;
- 要自定义界面或深度控制,选方案2更合适。
内容的提问来源于stack exchange,提问作者qwlice
相关产品推荐
相关产品推荐

