前言

即学即用Android Jetpack系列Blog的目的是通过学习Android Jetpack完成一个简单的Demo,本文是即学即用Android Jetpack系列Blog的第一篇。

记得去年第一次参加谷歌开发者大会的时候,就被Navigation的图形导航界面给迷住了,一句卧槽就代表了小王的全部心情~,我们可以看一下来自网络的一张图片:

所以,Android Jetpack学习之旅就开始了。

image

本人打算每周学习一个组件(上图的左上区域),最后将所学的组件组成一个简单的Demo。同时,刚刚过去的2019年谷歌开发者大会宣布亲儿子Kotlin成为开发Android的首选语言,所以本文的Demo也将都会采用Kotlin编写。

本章结束后登录部分完成效果:

语言:Kotlin
Demo地址:https://github.com/mCyp/Hoo

目录

一、简介

1. 定义

Navigation是什么呢?谷歌的介绍视频上说:

Navigation是一个可简化Android导航的库和插件

更确切的来说,Navigation是用来管理Fragment的切换,并且可以通过可视化的方式,看见App的交互流程。这完美的契合了Jake Wharton大神单Activity的建议。

2. 优点

  • 处理Fragment的切换(上文已说过)
  • 默认情况下正确处理Fragment的前进和后退
  • 为过渡和动画提供标准化的资源
  • 实现和处理深层连接
  • 可以绑定ToolbarBottomNavigationViewActionBar
  • SafeArgs(Gradle插件) 数据传递时提供类型安全性
  • ViewModel支持

3. 准备

如果想要进行下面的学习,你需要 3.2 或者更高的Android studio

4. 学习方式

最好的学习方式仍然是通过官方文档,下面是官方的学习地址:
谷歌官方教程:Navigation Codelab
谷歌官方文档:Navigation
官方Demo:Demo地址

二、实战

在实战之前,我们先来了解一下Navigation中最关键的三要素,他们是:

名词 解释
Navigation Graph(New XML resource) 如我们的第一张图所示,这是一个新的资源文件,用户在可视化界面可以看出他能够到达的Destination(用户能够到达的屏幕界面),以及流程关系。
NavHostFragment(Layout XML view) 当前Fragment的容器
NavController(Kotlin/Java object) 导航的控制者

可能我这么解释还是有点抽象,做一个不是那么恰当的比喻,我们可以将Navigation Graph看作一个地图,NavHostFragment看作一个车,以及把NavController看作车中的方向盘,Navigation Graph中可以看出各个地点(Destination)和通往各个地点的路径,NavHostFragment可以到达地图中的各个目的地,但是决定到什么目的地还是方向盘NavController,虽然它取决于开车人(用户)。

第一步 添加依赖

模块层的build.gradle文件需要添加:

ext.navigationVersion = "2.0.0"
dependencies {//... implementation "androidx.navigation:navigation-fragment-ktx:$rootProject.navigationVersion"implementation "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion"
}

如果你要使用SafeArgs插件,还要在项目目录下的build.gradle文件添加:

buildscript {ext.navigationVersion = "2.0.0"dependencies {classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"}
}

以及模块下面的build.gradle文件添加:

apply plugin: 'kotlin-android-extensions'
apply plugin: 'androidx.navigation.safeargs'

第二步 创建navigation导航

  1. 创建基础目录:资源文件res目录下创建navigation目录 -> 右击navigation目录New一个Navigation resource file

  2. 创建一个Destination,如果说navigation是我们的导航工具,Destination是我们的目的地,在此之前,我已经写好了一个WelcomeFragmentLoginFragmentRegisterFragment,添加Destination的操作完成后如下所示:

    除了可视化界面之外,我们仍然有必要看一下里面的内容组成,login_navigation.xml:

<navigation...android:id="@+id/login_navigation"app:startDestination="@id/welcome"><fragmentandroid:id="@+id/login"android:name="com.joe.jetpackdemo.ui.fragment.login.LoginFragment"android:label="LoginFragment"tools:layout="@layout/fragment_login"/><fragmentandroid:id="@+id/welcome"android:name="com.joe.jetpackdemo.ui.fragment.login.WelcomeFragment"android:label="LoginFragment"tools:layout="@layout/fragment_welcome"><action.../><action.../></fragment><fragmentandroid:id="@+id/register"android:name="com.joe.jetpackdemo.ui.fragment.login.RegisterFragment"android:label="LoginFragment"tools:layout="@layout/fragment_register"><argument.../></fragment>
</navigation>

我在这里省略了一些不必要的代码。让我们看一下navigation标签的属性:

属性 解释
app:startDestination 默认的起始位置

第三步 建立NavHostFragment

我们创建一个新的LoginActivity,在activity_login.xml文件中:

<androidx.constraintlayout.widget.ConstraintLayout...><fragmentandroid:id="@+id/my_nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"app:navGraph="@navigation/login_navigation"app:defaultNavHost="true"android:layout_width="match_parent"android:layout_height="match_parent"/></androidx.constraintlayout.widget.ConstraintLayout>

有几个属性需要解释一下:

属性 解释
android:name 值必须是androidx.navigation.fragment.NavHostFragment,声明这是一个NavHostFragment
app:navGraph 存放的是第二步建好导航的资源文件,也就是确定了Navigation Graph
app:defaultNavHost="true" 与系统的返回按钮相关联

第四步 界面跳转、参数传递和动画

WelcomeFragment中,点击登录和注册按钮可以分别跳转到LoginFragmentRegisterFragment中。

这里我使用了两种方式实现:

方式一 利用ID导航

目标:WelcomeFragment携带keyname的数据跳转到LoginFragmentLoginFragment接收后显示。
Have a account ? Login按钮的点击事件如下:

btnLogin.setOnClickListener {// 设置动画参数val navOption = navOptions {anim {enter = R.anim.slide_in_rightexit = R.anim.slide_out_leftpopEnter = R.anim.slide_in_leftpopExit = R.anim.slide_out_right}}// 参数设置val bundle = Bundle()bundle.putString("name","TeaOf")findNavController().navigate(R.id.login, bundle,navOption)
}

后续LoginFragment的接收代码比较简单,直接获取Fragment中的Bundle即可,这里不再出示代码。最后的效果:

方式二 利用Safe Args

目标:WelcomeFragment通过Safe Args将数据传到RegisterFragmentRegisterFragment接收后显示。
再看一下已经展示过的login_navigation.xml

<navigation...><fragment.../><fragmentandroid:id="@+id/welcome"><actionandroid:id="@+id/action_welcome_to_login"app:destination="@id/login"/><actionandroid:id="@+id/action_welcome_to_register"app:enterAnim="@anim/slide_in_right"app:exitAnim="@anim/slide_out_left"app:popEnterAnim="@anim/slide_in_left"app:popExitAnim="@anim/slide_out_right"app:destination="@id/register"/></fragment><fragmentandroid:id="@+id/register"...><argumentandroid:name="EMAIL"android:defaultValue="2005@qq.com"app:argType="string"/></fragment>
</navigation>

细心的同学可能已经观察到navigation目录下的login_navigation.xml资源文件中的action标签和argument标签,这里需要解释一下:
action标签

属性 作用
app:destination 跳转完成到达的fragment的Id
app:popUpTo fragment中弹出,直到某个Id的fragment

argument标签

属性 作用
android:name 标签名字
app:argType 标签的类型
android:defaultValue 默认值

点击Android studio中的Make Project按钮,可以发现系统为我们生成了两个类:

image

WelcomeFragment中的JOIN US按钮点击事件:

btnRegister.setOnClickListener {val action = WelcomeFragmentDirections.actionWelcomeToRegister().setEMAIL("TeaOf1995@Gamil.com")findNavController().navigate(action)
}

RegisterFragment中的接收:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// ...val safeArgs:RegisterFragmentArgs by navArgs()val email = safeArgs.emailmEmailEt.setText(email)
}

以及效果:

需要提及的是,如果不用Safe Argsaction可以由Navigation.createNavigateOnClickListener(R.id.next_action, null)方式生成,感兴趣的同学可以自行编写。

三、更多

Navigation可以绑定menusdrawersbottom navigation,这里我们以bottom navigation为例,我先在navigation目录下新创建了main_navigation.xml,接着新建了MainActivity,下面则是activity_main.xml:

<LinearLayout...><fragmentandroid:id="@+id/my_nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="match_parent"app:navGraph="@navigation/main_navigation"app:defaultNavHost="true"android:layout_height="0dp"android:layout_weight="1"/><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/navigation_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/white"app:itemIconTint="@color/colorAccent"app:itemTextColor="@color/colorPrimary"app:menu="@menu/menu_main"/></LinearLayout>

MainActivity中的处理也十分简单:

class MainActivity : AppCompatActivity() {lateinit var bottomNavigationView: BottomNavigationViewoverride fun onCreate(savedInstanceState: Bundle?) {//...val host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragmentval navController = host.navControllerinitWidget()initBottomNavigationView(bottomNavigationView,navController)}private fun initBottomNavigationView(bottomNavigationView: BottomNavigationView, navController: NavController) {bottomNavigationView.setupWithNavController(navController)}private fun initWidget() {bottomNavigationView = findViewById(R.id.navigation_view)}
}

效果:

四、总结

上图概括了本文的一些知识点,当然还有一些知识点没有涉及,比如深层连接等,其次,本文只是一篇入门型博客,关于更深层次的学习,本人会逐步进行。本人水平有限,文章难免有误,欢迎指正。

现学现用Android Jetpack - Navigation相关推荐

  1. 现学现卖做一个炫酷的动态背景页面

    很喜欢酷炫的页面,自从看了抖音的主页之后(如下)(链接),就决定要也做一个牛逼的动态背景页面 对...背景是视频,而且还有音效,太牛逼了 然后决定自己做一个,废话不说,先弄代码: 这里为了设计简便,用 ...

  2. 现学现卖微信小程序开发(二)

    现学现卖微信小程序开发(一) 现学现卖微信小程序开发(三):引入Rx,为小程序插上翅膀 一个Todo应用的小程序版 好的,那么下一步我们就先照猫画虎,新建一个todos文件夹,然后一套四样同名文件准备 ...

  3. 《Microduino实战》——3.5 I/O操作——现学现用

    本节书摘来自华章出版社<Microduino实战>一 书中的第3章,第3.5节,作者:姚琪 杨立斌,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 3.5 I/ ...

  4. CTF训练之现学现卖--SSH私钥泄露

    [原创]CTF训练之现学现卖–SSH私钥泄露 Step1 环境搭建: KALI官网下载vmware虚拟机 Virtual PC加载SSH-私钥泄露.ova (链接:https://pan.baidu. ...

  5. 零基础10小时学会3D基础建模,可能性有多大?现学现用现演示

    本期话题:10小时搞定零基础3D建模能实现么? 学习目标:分享3D建模思路,了解3D建模原理,10小时足够了. 工具软件: CimatronE13 UG NX12 Creo 6.0 SolidEdge ...

  6. 现学现用-我的第三个小小小私活

    之前写的博客 现学现用-我的第二个小小小私活 之前两个小小小私活,这次遇到的是第三个. 经历的大致历程: 一.背景 经朋友搭线介绍,一家公司需要做个微信小游戏,问我有没有时间和兴趣,我说可以做.做过小 ...

  7. 现学现用大数据分布式集群环境部署

    导读:        随着大数据时代的到来,传统的GIS分析工具越来越难以满足对超大体量空间数据的分析需求.SuperMap iServer 9D(本文简称iServer)实现了地理信息服务的分布式集 ...

  8. Android Jetpack Navigation 深入体验报告

    Android Jetpack 之 Navigation深入体验报告 前言 当前Android开发中使用Fragment来开发页面已经成为主流做法.Fragment轻量.可控性强等优点让人感觉很香. ...

  9. Android Jetpack Navigation组件(四):DeepLink(深链接)

    目录 前言 一.DeepLink定义 二.显式DeepLink 1.简介 2.创建显式DeepLink 3.NavDeepLinkBuilder接口说明 (1).NavDeepLinkBuilder( ...

最新文章

  1. cmw500综合测试仪使用_大屏幕真彩色互感器综合特性测试仪功能特点
  2. 四则运算栈c语言程序,四则运算   c语言编程
  3. 欲善其事,先利其器 | IDCF第6期DevOps案例研究回顾(附视频)
  4. .NET Core开发日志——结构化日志
  5. 第一百一十八天 how can I 坚持
  6. use texstudio with chinese on ubuntu
  7. Linux 内核的壳 —— shell
  8. metasploit联动beef启动
  9. Python爬虫基础-02-提取数据
  10. editview软键盘弹出和隐藏
  11. Textbox的用法
  12. Drools教程(基础篇)——Eclipse下Drools运行时安装
  13. unexpectedly exited. Status code was
  14. linux抓取vlan数据包,如何抓取 带VLAN tag的包
  15. java 监听客户端的退出_Java socket 服务端如何监控客户端异常关闭?
  16. ffmpegguitool下载不了_FFmpeg GUI Tool下载|FFmpeg GUI Tool(视频处理)下载v1.2.4 安卓版
  17. spf13/viper
  18. 分析java程序在运行中卡顿
  19. C#利用绝对值打印菱形
  20. OCR:光学字符识别技术

热门文章

  1. 【51单片机实验笔记】2. 数码管的基本控制
  2. 计算机外设配件的主要相关参数有哪些,电脑配件有哪些
  3. 读书笔记-《ON JAVA 中文版》-摘要9[第九章 多态]
  4. 蔚来汽车提前批2022年7月13日
  5. Initialization of bean failed; nested exception is java.lang.reflect.MalformedParameterizedTypeExce
  6. 随机过程 更新过程(下)
  7. excel2010 中 启用宏,VBA使用 说明
  8. 尼甘布 小渔村的惬意生活
  9. 【常见面试题】性能测试里,压力测试、负载测试、并发测试、强度测试、容量测试,具体是什么意思
  10. Android x86 手动安装houdini