先在布局文件中去掉app:navGraph="@navigation/mobile_navigation",然后来到activity,编写如下代码, //NavigationActivity.java navGraph = initNavGraph(provider, fragmentNavigator); //设置导航图 navController.setGraph(navGraph initNavGraph(NavigatorProvider provider, FixFragmentNavigator fragmentNavigator) { NavGraph navGraph (destination1); //省略 navGraph.addDestination(destination2); //省略 navGraph.addDestination (destination3); navGraph.setStartDestination(R.id.navigation_home); return navGraph; } 具体流程都写在代码注释里了
特殊的Destination,将app:navGraph="@navigation/nav_graph解析封装成NavGraph对象,里面包含nav_graph.xml中的所有信息。 首先我们知道NavGraph中是包含nav_graph所有节点的内容。 (this) this=NavGraphNavigator: 跟进: public NavGraph createDestination() { return new NavGraph (this); } public NavGraph(@NonNull Navigator<? 同时在递归中把所有NavDestination节点addDestination()到NavGraph中: NavGraph: SparseArrayCompat<NavDestination> mNodes
layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph 方式一: google的demo中是在MainActivity中创建一个main_navGraph,其中包含了不同子moduel的navGraph ,如下: <? app:graph="@navigation/navi_center"/> </navigation> navi_home 、navi_collection 、navi_center是子moduel中的navGraph 方式二: 因为app module本身是需要依赖各个子moduel的,我们可以在navGraph直接使用子moduel中的Fragment,主页面只需加入各个module的主Fragment就行了:
由此可见,导航资源文件nav_graph会被解析成一个NavGraph对象,看下NavGraph public class NavGraph extends NavDestination implements 继承了NavDestination,NavDestination其实就是nav_graph.xml中navigation下的一个个节点,也就是一个个页面,NavGraph内部有个集合mNodes,用来保存一组 (destination instanceof NavGraph)) { throw new IllegalArgumentException("Root element <" + rootElement + ">" + " did not inflate into a NavGraph"); } return 那么我们是不能在布局文件中通过app:navGraph属性指定自定义的导航资源文件了,只能在布局文件中去掉app:navGraph这个属性,然后在添加FixFragmentNavigator的同时,通过代码将导航资源文件设置进去
new TypeReference<HashMap<String, Destination>>() { }.getType()); /** * 创建NavGraph 它是解析mobile_navigation.xml文件后,存储所有节点的Destination * 我们解析的Destination节点,最终都要存入NavGraph中 NavGraph navGraph = new NavGraph(navigator); //创建我们自定义的FragmentNavigator HiFragmentNavigator (destination.id); } } // 视图navGraph和controller 相关联 controller.setGraph (navGraph); } private static String parseFile(Context context, String fileName) {
--app:navGraph="@navigation/mobile_navigation"设置Fragment对应的导航图--> <fragment android:id="@+id/ match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph initNavGraph(NavigatorProvider provider, FixFragmentNavigator fragmentNavigator) { NavGraph navGraph = new NavGraph(new NavGraphNavigator(provider)); //用自定义的导航器来创建目的地 FragmentNavigator.Destination (destination3); navGraph.setStartDestination(destination1.getId()); return navGraph
FragmentContainerView是一个特殊的Fragment,只能添加Fragment, app:navGraph:这里需要指定前面在res文件夹下创建的navigation文件 app:defaultNavHost NavOptions.Builder() .setPopUpTo(R.id.fragmentOne, true) .build() Navigation动态加载 除了在xml中设置navGraph ,有很多场景下,我们会根据业务场景动态设置一些navGraph,或者某些navGraph是需要动态获取一些参数之后才去初始化的,这时候,就可以使用Navigation的动态加载方案。 首先,需要在Fragment容器中,去掉navGraph的引用,然后在Activity中,动态指定要引用的navGraph,代码如下所示。 R.id.loginFragment navHostFragment.navController.graph = navigation 实际上和动态Inflate布局再添加布局到容器的场景非常类似,Navigation动态加载也是将navGraph
popBackStack()回退上一级时有什么区别,该如何正确使用 跳转时 有时用的是Action的ID,有时用的是Fragment的ID 他俩到底在什么场景下,区分该将哪个传入方法作为参数 使用和核心方法 1.创建NavGraph app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph ="@navigation/nav_graph" /> 以上3个配置比较重要: app:defaultNavHost="true" app:navGraph="@navigation/nav_graph 拦截返回键的点击事件,这样Fragment就可以想Activity一样,具有回退,返回事件 配置路由XML文件,然后加载进NavHostFragment中 app:navGraph属性,对应的就是NavGraph 代码实现路由跳转和方法解析 3.1 核心方法 Acitivty#findNavController() 传入navGraph id Fragment#findNavController() 直接调用
image.png FragmentContainerView是一个特殊的Fragment,只能添加Fragment, app:navGraph:这里需要指定前面在res文件夹下创建的navigation NavOptions.Builder() .setPopUpTo(R.id.fragmentOne, true) .build() Navigation动态加载 除了在xml中设置navGraph ,有很多场景下,我们会根据业务场景动态设置一些navGraph,或者某些navGraph是需要动态获取一些参数之后才去初始化的,这时候,就可以使用Navigation的动态加载方案。 首先,需要在Fragment容器中,去掉navGraph的引用,然后在Activity中,动态指定要引用的navGraph,代码如下所示。 R.id.loginFragment navHostFragment.navController.graph = navigation 实际上和动态Inflate布局再添加布局到容器的场景非常类似,Navigation动态加载也是将navGraph
Fragment,这个Fragment的name是androidx.navigation.fragment.NavHostFragment,这是一个添加到布局中的特殊部件,NavHostFragment通过navGraph :layout_height="match_parent" app:defaultNavHost="true" app:navGraph 接下来我们看到为NavController设置了setGraph(),也就是我们xml里面定义的navGraph,导航布局里面的Fragment及action跳转等信息。 3.2 NavController /** * Sets the {@link NavGraph navigation graph} to the specified graph. = new ArrayDeque<>(); NavGraph parent = newDest.getParent(); while (parent !
layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph
Navigation是一种导航的概念,即把Activity和fragment当成一个个的目的地Destination,各目的地形成一张导航图NavGraph,由导航控制器NavController来统一调度跳转 -- fragment作为页面容器,navGraph指定了导航图的结构 --> <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true" app:navGraph
Fragment,这个Fragment的name是androidx.navigation.fragment.NavHostFragment,这是一个添加到布局中的特殊部件,NavHostFragment通过navGraph :layout_height="match_parent" app:defaultNavHost="true" app:navGraph 接下来我们看到为NavController设置了setGraph(),也就是我们xml里面定义的navGraph,导航布局里面的Fragment及action跳转等信息。 3.2 NavController /** * Sets the {@link NavGraph navigation graph} to the specified graph. = new ArrayDeque<>(); NavGraph parent = newDest.getParent(); while (parent !
Fragment,这个Fragment的name是androidx.navigation.fragment.NavHostFragment,这是一个添加到布局中的特殊部件,NavHostFragment通过navGraph :layout_height="match_parent" app:defaultNavHost="true" app:navGraph 接下来我们看到为NavController设置了setGraph(),也就是我们xml里面定义的navGraph,导航布局里面的Fragment及action跳转等信息。 3.2 NavController /** * Sets the {@link NavGraph navigation graph} to the specified graph. = new ArrayDeque<>(); NavGraph parent = newDest.getParent(); while (parent !
match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph 布局 在 Activity 的布局文件中 , 添加如下代码 , 不建议在 Design 界面直接拖动 NavHostFragment , 生成的代码报错 , 直接拷贝下面的代码即可 ; 将 app:navGraph android:layout_width="match_parent" android:layout_height="match_parent" app:navGraph android:layout_width="match_parent" android:layout_height="match_parent" app:navGraph
layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph androidx.navigation.fragment.NavHostFragment ; 查看 app:defaultNavHost=“true” 属性是否设置 ; 查看 NavigationGraph 的设置 app:navGraph
match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph 使用 android:name 指定 Fragment 的类型为 NavHostFragment,使用 app:navGraph 指定 Navigation 文件。
my_nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" app:navGraph my_nav_host_fragment" android:name="com.demo.navigationcomponent.TabNavHostFragment" app:navGraph
下面的文章中,我将介绍 ViewModel 的四种集成方式: ViewModel 中的 Saved State —— 后台进程重启时,ViewModel 的数据恢复; 在 NavGraph 中使用 ViewModel ViewModel 与 Jetpack 导航: 在 NavGraph 中使用 ViewModel 于 navigation 的 2.1.0-rc01 版本时加入 支持 Java 与 Kotlin 共享 ViewModel 与 NavGraph 集成 Navigation 2.1.0 中引入了依托一个导航图 (navigation graph) 创建 ViewModel 的功能。 ViewModel 与 NavGraph 的集成,是 2019 年 I/O 大会所发布的关于 Navigation 框架的新特性之一。
match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph