使用Jetpack Navigation时如何在Activity中获取NavController?
问题原因
你在Activity A中执行supportFragmentManager.findFragmentById(R.id.nav_host_fragment)时,该API只会在当前Activity A的布局树中查找对应ID的组件。你的nav_host_fragment只存在于MainActivity的布局中,Activity A布局没有对应实例,所以返回null,强转为非空的NavHostFragment类型就会触发崩溃。
解决方案
根据你的导航目标不同,对应实现方式如下:
场景1:从Activity A跳转到其他Activity(如Activity B)
无需依赖NavController,直接使用原生API跳转即可:
startActivity(Intent(this@ActivityA, ActivityB::class.java)) // 按需添加flag或者传参即可
场景2:从Activity A跳转到MainActivity所属导航图的Fragment FB
需要通过Intent给MainActivity传递目标标识,由MainActivity的NavController执行导航:
- 在Activity A中执行跳转逻辑:
val intent = Intent(this@ActivityA, MainActivity::class.java).apply { putExtra("nav_target", R.id.fragmentFB) // 传入Fragment FB在导航图中的ID // 按需添加其他参数 } startActivity(intent) // 按需调用finish()关闭当前Activity A
- 在MainActivity的
onCreate方法中接收参数并执行导航:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 先初始化NavController val navHost = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHost.navController // 处理跳转参数 val targetDest = intent.getIntExtra("nav_target", 0) if (targetDest != 0) { navController.navigate(targetDest) // 用完记得移除参数,避免屏幕旋转等场景重复跳转 intent.removeExtra("nav_target") } }
场景3:Activity A内部需要管理自己的Fragment导航
需要先给Activity A添加专属的NavHost:
- 在Activity A的布局文件中添加
FragmentContainerView作为NavHost:
<androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_activity_a" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:navGraph="@navigation/your_nav_graph_for_activity_a" />
- 在Activity A中获取对应NavController后执行导航:
// 注意要在setContentView之后调用 val navHost = supportFragmentManager.findFragmentById(R.id.nav_host_activity_a) as NavHostFragment val navController = navHost.navController // 跳转到对应Fragment navController.navigate(R.id.action_to_fragmentFB)
注意事项
- 禁止跨Activity直接获取其他Activity的NavHost实例,不同Activity的FragmentManager是隔离的
- 所有查找NavHost的操作必须在
setContentView执行完成后调用,否则布局未加载也会返回null
内容的提问来源于stack exchange,提问作者Bernhard Josephus
相关产品推荐
相关产品推荐

