Navigation 动态注册跳转:

4 阅读2分钟

一句话讲透:不是写死在 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 动态注册跳转 = 代码手动添加页面 + 代码手动加跳转规则

步骤固定:

  1. 获取 NavController
  2. 获取 NavGraph
  3. 创建 FragmentNavigator.Destination
  4. 设置 id + class name
  5. graph.addDestination()
  6. 就能 navigate()