Android Jetpack(六)Navigation

╄→гoц情女王★ 提交于 2020-02-21 19:06:05

一、Navigation 介绍        

        Navigation 是 Jetpack 组件库的一个组件,可以方便的管理 Fragment ,可以看作是针对于 Fragment 的路由。 功能主要是:用于管理 APP 页面跳转导航,同时,切换 Fragment 变得更加直观,通过可视化界面展示 Fragment 的切换流程图。

        利用 Navigation 组件对 Fragment 的原生支持,可以获得架构组件的所有好处(例如生命周期和 ViewModel),同时让此组件来处理 FragmentTransaction 的复杂性。此外,Navigation 组件还可以处理转场动画。它可以自动构建正确的“向上”和“返回”行为,包含对深层链接的完整支持,并提供了帮助程序,用于将导航关联到合适的 UI 小部件,例如抽屉式导航栏和底部导航。

        除此之外,Navigation 最大的一个好处是:让单 Activity 应用成为首选架构(即:单 Activity + 多 Fragment。应用内  Fragment 页面的跳转则由 Navigation 来处理,开发者无需在处理 FragmentTransaction 的复杂性以及相关的转场动画。

 

二、Navigation 核心概念

  • NavGraph:导航图,一个 XML 资源,它包含集中在一个位置上的所有与导航相关的信息。这包括所有单独的内容区域(destination),以及用户可以通过应用程序访问的可能路径。就类似一个流程图,如下图。
  • NavHost:显示导航图中的 Destination 的容器。导航组件包含一个默认的 NavHost 实现 NavHostFragment。
  • NavController: 控制 NavHost 容器内容的切换的控制器
  • Destination:目的片段,一般是 Fragment (由于 google 推荐单 Activity 模式 APP),也可以是 Activity。如下图的三个界面。
  • Action:动作,就相当于 intent,表示从一个 Destination 到另一个 Destination,如下图的箭头。

        

         

 

三、Navigation 使用

1. 导入依赖库

implementation 'androidx.navigation:navigation-fragment:2.2.1'
implementation 'androidx.navigation:navigation-ui:2.2.1'

2. 创建一个Activity和多个Fragment

        按照业务逻辑创建,假设创建了MainActivity、FragmentA、FragmentB。

3. 新建 Navigation

  • res 目录右键 New->New Resource File,弹出 New Resource File 的对话框
  • 填写 File Name 如:nav_graph,Resource type 选择 Navigation,点击OK

4. 使用 Navigation

        打开 nav_graph.xml,底部选择 Design 选项卡,点击 New Destination (左上角 + ) 按钮,在弹窗中选择
fragment_a.xmlfragment_b.xml;

        或选择 Create blank destination 新建 Fragment 之后选显示如下界面:

        

5. 添加 NavHostFragment

        在 Activity 布局里添加 NavHostFragment,并将 NavHostFragment 跟我们刚才创建的 navigation 关联。

如果是采用拖动添加的方式,会弹出一个包含导航图列表的对话框,选择创建的 navigation 即可;也可以使用代码指定

app:navGraph="@navigation/nav_graph"

         

6. 添加 Action 

        左键按住 fragment 右侧中间的圆圈然后拖动到要导航的 fragment 然后松手。

        

7. NavController 处理 Action 跳转

        跳转需要通过 NavController 对象的 navigate(int id) 方法来跳转。

        NavController对象获取的三种方式

  • NavHostFragment.findNavController(Fragment)
  • Navigation.findNavController(Activity, @IdRes int viewId)
  • Navigation.findNavController(View)
   override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Navigation.findNavController(view)
        button.setOnClickListener {
                    //id就是nav_graph导航图里面的action id
            Navigation.findNavController(view).navigate(R.id.action_blankFragment_to_secondeFragment)
        }
    }

        如果是返回,就调用 navigateUp()方法。

 

四、Navigation 拓展

1. Navigation 传参

(1)代码传参

        可以使用 Bundle 传参:

 Bundle bundle = new Bundle();
 bundle.putString("param", "I AM FROM FRAGMENT-A");
 Navigation.findNavController(it).navigate(R.id.action_fragmentA_to_fragmentC, bundle);

 (2)导航图传参

        如 A 传参到 B,在导航图设计页面,单击 destination B ,在右边的属性栏添加 Argument,弹出如下窗口:

        

        创建成功后,fragment 标签中添加 argument 标签如下:

<argument
    android:name="name"
    android:defaultValue="no"
    app:argType="string" />

        之后可通过两种方式传递参数:

  • FragmentBArgs
  • FragmentADirections

        它们都是自动生成的,FragmentBArgs 是根据fragment 节点下的 argument 节点生成的;FragmentADirections 是根据 action 生成的。

        使用生成的对应的 Agrs 或者 Directions 来传递参数,需要导入 apply plugin: 'androidx.navigation.safeargs'。

//使用FragmentBArgs
val bundle = FragmentBArgs.Builder().setText("Hello World").build().toBundle()
Navigation.findNavController(it).navigate(R.id.action_fragmentA_to_fragmentB, bundle)

//使用FragmentADirections
val direction = FragmentADirections.action_fragmentA_to_fragmentB().setText("Hello World")
Navigation.findNavController(it).navigate(direction)

2. Navigation 动画

        点击箭头,右边属性栏有个Animations列表。默认都是null,可以设置官方自带的进出栈动画,也可以设置自定义动画。

        

 

  • Enter 进入一个目的地 (例如 A跳B, B显示时执行的动画)
  • Exit 退出一个目的地 (例如 A跳B,A隐藏时执行的动画)
  • Pop Enter通过 pop 操作进入目的地 (例如 A跳B,B navigateUp 后 A再次出现时执行的动画)
  • Pop Exit 通过pop 操作退出目的地 (例如 A跳B,B navigateUp 后 B消失时执行的是这个动画)

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!