一句话讲透:不是写死在 nav_graph.xml 里,而是代码里动态添加 Destination、动态添加 Action、动态跳转,适合组件化、多模块、运行时才知道跳转规则的场景。
我给你最实用、最精简、能直接用的总结。
一、什么是 “动态注册跳转”?
**静态(平时写法)**XML 写死页面 → 编译时确定
xml
<fragment
android:id="@+id/homeFragment"
android:name="com.xxx.HomeFragment"/>
动态(你要的) 代码里手动创建页面、手动加路由、手动绑定跳转运行时才决定去哪里 → 灵活、组件化必备
二、核心 API(记住这 4 个)
java
运行
// 1. 获取控制器
NavController controller = Navigation.findNavController(view);
// 或
NavController controller = navHostFragment.getNavController();
// 2. 获取导航图(必须)
NavGraph graph = controller.getGraph();
// 3. 创建目的地(Fragment)
NavDestination destination = new FragmentNavigator.Destination(controller.getNavigatorProvider(), FragmentNavigator.class);
destination.setId(R.id.home_fragment); // 自定义ID
destination.setClassName(HomeFragment.class.getName());
// 4. 添加到导航图
graph.addDestination(destination);
// 5. 动态添加跳转 Action(可选)
NavAction action = new NavAction(R.id.target_fragment);
graph.addAction(R.id.action_to_target, action);
三、最常用:动态添加 Fragment 页面
java
运行
// 1. 拿到导航图
NavController navController = navHostFragment.getNavController();
NavGraph navGraph = navController.getGraph();
// 2. 创建目的地
FragmentNavigator.Destination dest = new FragmentNavigator.Destination(
navController.getNavigatorProvider(),
FragmentNavigator.class
);
// 3. 设置ID + 类路径
dest.setId(R.id.my_dynamic_fragment);
dest.setClassName(MyFragment.class.getName());
// 4. 添加到导航图
navGraph.addDestination(dest);
添加完就能直接跳:
java
运行
navController.navigate(R.id.my_dynamic_fragment);
四、动态注册 Action(跳转规则)
java
运行
// 给 navGraph 动态加跳转规则:从 A → B
NavAction action = new NavAction(R.id.fragmentB);
navGraph.addAction(R.id.action_A_to_B, action);
用:
navController.navigate(R.id.action_A_to_B);
五、动态设置起始页
java
运行
navGraph.setStartDestination(R.id.homeFragment);
navController.setGraph(navGraph); // 重新设置才生效
六、你项目里最可能的用法(组件化)
java
运行
// 其他模块通过 ARouter 拿到路径
String path = "/main/home";
Class<? extends Fragment> fragmentClass = ARouter.getInstance().build(path).getFragmentClass();
// 动态添加到 Navigation
FragmentNavigator.Destination dest = ...;
dest.setClassName(fragmentClass.getName());
graph.addDestination(dest);
真正意义:模块之间不互相依赖,动态注册页面。
七、动态注册 vs 静态 XML
表格
| 方式 | 静态 XML | 动态代码 |
|---|---|---|
| 时机 | 编译时 | 运行时 |
| 灵活度 | 低 | 高 |
| 组件化 | 不方便 | 非常方便 |
| 适用 | 固定页面 | 多模块、插件化、动态页面 |
八、超级总结(背这一段)
Navigation 动态注册跳转 = 代码手动添加页面 + 代码手动加跳转规则
步骤固定:
- 获取
NavController - 获取
NavGraph - 创建
FragmentNavigator.Destination - 设置 id + class name
graph.addDestination()- 就能
navigate()