一、导航概述

Navigation 用于 Fragment 的管理。他可以让 Fragrant 之间的切换,拥有像 Activity 间一样的跳转。与 DrawerLayout(抽屉式布局)、ActionBar(导航栏)等有简洁完美的对接。

二、开发环境设置

注意:Navigation 需要在 Android Studio 3.3 或更高版本中才可使用。(并且在 androidx 中支持的更好,之前没有使用 androidx 一直无法添加 Fragment 目的地)

若要在项目中包含导航支持,请将以下依赖项添加到应用程序的 build.gradle 文件中:

dependencies {def nav_version = "2.1.0-rc01"// Javaimplementation "androidx.navigation:navigation-fragment:$nav_version"implementation "androidx.navigation:navigation-ui:$nav_version"// Kotlinimplementation "androidx.navigation:navigation-fragment-ktx:$nav_dep"implementation "androidx.navigation:navigation-ui-ktx:$nav_dep"}

三、创建 navigation graph (导航图)

导航图是一个 XML 资源文件,在导航图中有两个概念:

1.Destination:导航图中的每一个导航被称为 Destination (目的地)。

2.Action:导航与导航之间使用 Action (事件) 连接,用于说明两个导航之间的跳转关系。

若要向项目添加导航图,请执行以下操作:

在项目的 res 目录下,新建一个 navigation 文件夹,右键 navigation 文件夹,依次选择:NewNavigation resource file

填写文件名称,如:nav_graph,点击 OK。

四、编辑导航图

在编辑导航图前,需要先创建 Activity,与相关的 Fragment。(此处使用 1 个 Activity,三个 Fragment)

/*** @Author: Eli Shaw* @Date: 2019-08-18 10:10:42* @Description: Activity 容器类*/
class NavigationActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_navigation)}
}
/*** @Author: Eli Shaw* @Date: 2019-08-18 10:07:13* @Description: 登录页*/
class LoginFragment : Fragment(), View.OnClickListener {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentval viewRoot = inflater.inflate(R.layout.fragment_login, container, false)return viewRoot}
}
/*** @Author: Eli Shaw* @Date: 2019-08-18 10:08:52* @Description: 注册页*/
class RegisterFragment : Fragment(), View.OnClickListener {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentval viewRoot = inflater.inflate(R.layout.fragment_register, container, false)return viewRoot}
}
/*** @Author: Eli Shaw* @Date: 2019-08-18 10:40:42* @Description: 首页*/
class HomeFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_home, container, false)}
}

创建好 nav_graph 导航图后,双击进行编辑(与常规布局文件很相似)

1、指定 Activity 容器

在 Activity 布局文件中指定导航图的容器

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".navigation.NavigationActivity"><fragmentandroid:id="@+id/nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true"app:navGraph="@navigation/nav_graph"/>
</LinearLayout>

android:name:指定 Fragment 的类型为 NavHostFragment。

app:defaultNavHost="true":让 Navigation 容器处理返回事件,在 Navigation 容器中如果有页面的跳转,点击返回按钮会先处理 容器中 Fragment 页面间的返回,处理完容器中的页面,再处理 Activity 页面的返回。如果值为 false 则直接处理 Activity 页面的返回。

app:navGraph:指定 Navigation 文件。

2、添加 Action (事件)

拖动选中的(目的地)右方的圆点到另一个(目的地)即可创建一个 Action(事件)。

点击左下角的 Text ,将显示如下代码

<navigation xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/nav_graph"app:startDestination="@id/loginFragment"><!--登录 Fragment 包含两个事件:一个是注册页,一个是首页 --><fragment android:id="@+id/loginFragment" android:name="cn.eli.jetpack.navigation.LoginFragment"android:label="fragment_login" tools:layout="@layout/fragment_login"><action android:id="@+id/actionLoginToRegister" app:destination="@id/registerFragment"/><action android:id="@+id/actionLoginToHome" app:destination="@id/homeFragment"/></fragment><!--注册 Fragment 包含一个事件:返回到登录页--><fragment android:id="@+id/registerFragment" android:name="cn.eli.jetpack.navigation.RegisterFragment"android:label="fragment_register" tools:layout="@layout/fragment_register"><action android:id="@+id/actionRegisterToLogin" app:destination="@id/loginFragment"/></fragment><!--首页 Fragment 没有事件--><fragment android:id="@+id/homeFragment" android:name="cn.eli.jetpack.navigation.HomeFragment"android:label="fragment_home" tools:layout="@layout/fragment_home"/>
</navigation>

3、导航图的复用

<navigation> 是导航图的根元素,Destination (目的地) 与 Action (事件) 都是 <navigation> 元素中的节点。

<navigation> 中可以包含 <navigation> 节点,这样使用的目的是可以复用相同的导航图。例如:增加一个找回密码页,这个找回密码页在另一个导航图中,找回密码后再继续登录操作:

此图是一个包含导航图的预览页,文本内容如下

<navigation xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_multiplex"app:startDestination="@id/findPwdFragment"><fragment android:id="@+id/findPwdFragment" android:name="cn.eli.jetpack.navigation.FindPwdFragment"android:label="fragment_find_pwd" tools:layout="@layout/fragment_find_pwd"><action android:id="@+id/action_findPwdFragment_to_nav_graph" app:destination="@id/nav_graph"/></fragment><!--引入另一个导航图--><include app:graph="@navigation/nav_graph"/></navigation>

五、导航图间的跳转

1、获取 NavController 的方式

导航图使用 NavController 控制(目的地)之间的跳转,在 Activity,Fragment 中获取 NavController 有以下 6 种方式:

1.Fragment.findNavController()
2.View.findNavController()
3.Activity.findNavController(viewId: Int) //只有 Activity 中可以使用
4.NavHostFragment.findNavController(Fragment)
5.Navigation.findNavController(Activity, @IdRes int viewId) //只有 Activity 中可以使用
6.Navigation.findNavController(View)

2、导航中目的地间的传值

导航中目的地间也可以使用 Bundle 进行传值

//使用 bundle 传值
val bundle = Bundle()
bundle.putInt(ARG_NAV, navController)findNavController().navigate(R.id.actionLoginToRegister, bundle)

下面是登录页、注册页完整代码

private const val ARG_NAV = "nav"/*** @Author: Eli Shaw* @Date: 2019-08-18 10:07:13* @Description: 登录页*/
class LoginFragment : Fragment(), View.OnClickListener {private var navController: Int = 0override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {navController = it.getInt(ARG_NAV)}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentval viewRoot = inflater.inflate(R.layout.fragment_login, container, false)//注册点击事件viewRoot.findViewById<Button>(R.id.btnRegister).setOnClickListener(this)//登录点击事件viewRoot.findViewById<Button>(R.id.btnLogin).setOnClickListener {findNavController().navigate(R.id.actionLoginToHome)}return viewRoot}/*** 注册点击事件*/override fun onClick(view: View) {if (++navController > 4)navController = 1//使用 bundle 传值val bundle = Bundle()bundle.putInt(ARG_NAV, navController)//根据 navController 值的不同,使用不同的获取 NavController 的方式when (navController) {//Fragment.findNavController()1 -> findNavController().navigate(R.id.actionLoginToRegister, bundle)//View.findNavController()2 -> view.findNavController().navigate(R.id.actionLoginToRegister, bundle)//NavHostFragment.findNavController(Fragment)3 -> NavHostFragment.findNavController(this).navigate(R.id.actionLoginToRegister, bundle)//Navigation.findNavController(View)4 -> Navigation.findNavController(view).navigate(R.id.actionLoginToRegister, bundle)}}
}
private const val ARG_NAV = "nav"/*** @Author: Eli Shaw* @Date: 2019-08-18 10:08:52* @Description: 注册页*/
class RegisterFragment : Fragment(), View.OnClickListener {private var navController: Int = 0override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {navController = it.getInt(ARG_NAV)}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentval viewRoot = inflater.inflate(R.layout.fragment_register, container, false)viewRoot.findViewById<Button>(R.id.btnBackLogin).setOnClickListener(this)return viewRoot}override fun onClick(view: View) {val bundle = Bundle()bundle.putInt(ARG_NAV, navController)view.findNavController().navigate(R.id.actionRegisterToLogin, bundle)}
}

3、导航中目的地间的转场动画

自定义转场动画

cut_to_enter.xml (入场动画)

<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:toYDelta="0"android:fromYDelta="100%"android:duration="1500"/>
</set>

cut_to_exit.xml(出场动画)

<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="1500"android:fromYDelta="0"android:toYDelta="-100%"/>
</set>

在导航图中编辑

Android Navigation 详解相关推荐

  1. 学习Android从0开始之开发工具篇-Android studio详解

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android studio详解 我们古人又云:工欲善其事,必先利其器. 1.android studio的背景 Android Studio 是 ...

  2. 【转】Android菜单详解——理解android中的Menu--不错

    原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...

  3. Android菜单详解——理解android中的Menu

    前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...

  4. Android LayoutInflater详解

    Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...

  5. android Fragments详解

    android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...

  6. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

  7. android WebView详解,常见漏洞详解和安全源码(上)

    这篇博客主要来介绍 WebView 的相关使用方法,常见的几个漏洞,开发中可能遇到的坑和最后解决相应漏洞的源码,以及针对该源码的解析.  由于博客内容长度,这次将分为上下两篇,上篇详解 WebView ...

  8. android子视图无菜单,Android 菜单详解

    Android中菜单分为三种,选项菜单(OptionMenu),上下文菜单(ContextMenu),子菜单(SubMenu) 选项菜单 可以通过两种办法增加选项菜单,一是在menu.xml中添加,该 ...

  9. Android StateFlow详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121913352 本文出自[赵彦军的博客] 文章目录 系列文章 一.冷流还是热流 S ...

  10. Android SharedFlow详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121911675 本文出自[赵彦军的博客] 文章目录 系列文章 什么是SharedF ...

最新文章

  1. 类、抽象类、接口之间的区别
  2. Qt Creator导出3D资产Exporting 3D Assets
  3. 学会这个用这个做PPT,把24小时的工作变成1秒!高效神器保住你的发际线~
  4. CASS软件学习笔记
  5. python中try命令_Python 异常处理 Python 基础教程 try..except
  6. java native 关键字
  7. hadoop3.0.3 SLS-Failed to create an AM
  8. 电脑怎么开护眼模式_心累!整天对着手机电脑,到底该怎么护眼啊啊啊
  9. ES6新特性:Javascript中Generator(生成器)
  10. php 表单提交渲染问题,如何解决php表单提交的数据丢失的问题
  11. 怎么在个人网站开通支付宝付款功能
  12. 猫哥教你写爬虫 027--模块介绍
  13. phpcms v9整站模板开发
  14. mysql 瘦身_Mysql瘦身方法
  15. 合肥工业大学计组实验五
  16. Python二级试题(一)
  17. word文档打开密码解密怎么解
  18. DSL和RestClient实现搜索
  19. 独立mysql安装,LAMP中mysql独立安装
  20. 计算机跨考应用经济学,计算机专业跨考人大经济学复习经验谈br /

热门文章

  1. 解决俄罗斯大shen精简版Win10无法远程的问题及同类精简版系统无法远程问题,简单快捷方法。
  2. 网络安全与渗透测试工具导航
  3. 移动端常用Axure组件库 元件库下载 包含微信 支付宝常用组件元素
  4. [趣谈网络协议学习] 17 P2P协议:我下小电影, 99%急死你
  5. CSI Tool安装使用讲解
  6. win10 系统Docker搭建设备共享平台stf(三)
  7. 怎样给家庭组计算机授权,steam如何设置家庭共享?steam设置家庭共享方法
  8. java easyui样式_[EasyUI美化换肤]更换EasyUi图标
  9. python制作简单计算器
  10. 易宝支付php接口,【图片】易宝支付PHP版测试、懂的进【php吧】_百度贴吧