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
的前进和后退 -
为过渡和动画提供标准化的资源
-
实现和处理深层连接
-
可以绑定
Toolbar
、BottomNavigationView
和ActionBar
等 -
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导航
-
创建基础目录:资源文件
res
目录下创建navigation
目录 -> 右击navigation
目录New一个Navigation resource file
-
创建一个
Destination
,如果说navigation
是我们的导航工具,Destination
是我们的目的地,在此之前,我已经写好了一个WelcomeFragment
、LoginFragment
和RegisterFragment
,添加Destination
的操作完成后如下所示:
除了可视化界面之外,我们仍然有必要看一下里面的内容组成,login_navigation.xml
:
<navigation
…
android:id=“@+id/login_navigation”
app:startDestination=“@id/welcome”>
<fragment
android:id=“@+id/login”
android:name=“com.joe.jetpackdemo.ui.fragment.login.LoginFragment”
android:label=“LoginFragment”
tools:layout=“@layout/fragment_login”
/>
<fragment
android:id=“@+id/welcome”
android:name=“com.joe.jetpackdemo.ui.fragment.login.WelcomeFragment”
android:label=“LoginFragment”
tools:layout=“@layout/fragment_welcome”>
<action
…/>
<action
…/>
<fragment
android:id=“@+id/register”
android:name=“com.joe.jetpackdemo.ui.fragment.login.RegisterFragment”
android:label=“LoginFragment”
tools:layout=“@layout/fragment_register”
<argument
…/>
我在这里省略了一些不必要的代码。让我们看一下navigation标签
的属性:
| 属性 | 解释 |
| — | — |
| app:startDestination
| 默认的起始位置 |
第三步 建立NavHostFragment
我们创建一个新的LoginActivity
,在activity_login.xml
文件中:
<androidx.constraintlayout.widget.ConstraintLayout
…>
<fragment
android: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
中,点击登录和注册按钮可以分别跳转到LoginFragment
和RegisterFragment
中。
这里我使用了两种方式实现:
方式一 利用ID导航
目标:WelcomeFragment
携带key
为name
的数据跳转到LoginFragment
,LoginFragment
接收后显示。
Have a account ? Login
按钮的点击事件如下:
btnLogin.setOnClickListener {
// 设置动画参数
val navOption = navOptions {
anim {
enter = R.anim.slide_in_right
exit = R.anim.slide_out_left
popEnter = R.anim.slide_in_left
popExit = 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
将数据传到RegisterFragment
,RegisterFragment
接收后显示。
再看一下已经展示过的login_navigation.xml
:
<navigation
…>
<fragment
…
/>
<fragment
android:id=“@+id/welcome”
<action
android:id=“@+id/action_welcome_to_login”
app:destination=“@id/login”/>
<action
android: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
android:id=“@+id/register”
…
<argument
android:name=“EMAIL”
android:defaultValue=“2005@qq.com”
app:argType=“string”/>
细心的同学可能已经观察到navigation
目录下的login_navigation.xml
资源文件中的action
标签和argument
标签,这里需要解释一下:
action标签
| 属性 | 作用 |
如何做好面试突击,规划学习方向?
面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。
学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。
我们搜集整理过这几年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
我们在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
试突击,规划学习方向?**
面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。
学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。
我们搜集整理过这几年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
[外链图片转存中…(img-x8VZKJBb-1715343138998)]
我们在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!