在移动开发中,对开发者来说不同的人具有不同的能力。就像读一本书一样,一千个读者,有一千个哈姆雷特。但不管怎样,只要你是个软件开发者你就必须学习windows或Linux等操作系统的运行原理。就不扯这么多了直接上干货。
【由于文中篇幅较长,提前预告:文末有大量手写框架源码及架构思维资料,需要的可直接跳越至文末领取】
在实战之前,我们先来了解一下 Navigation 中最关键的三要素,他们是:
可能我这么解释还是有点抽象,做一个不是那么恰当的比喻,我们可以将 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'
Destination
,如果说
navigation
是我们的导航工具,
Destination
是我们的目的地,在此之前,我已经写好了一个
WelcomeFragment
、
LoginFragment
和
RegisterFragment
,添加
Destination
的操作完成后如下所示:
添加Destination
除了可视化界面之外,我们仍然有必要看一下里面的内容组成, login_navigation.xml :
我在这里省略了一些不必要的代码。让我们看一下 navigation标签 的属性:
app:startDestination 默认的起始位置
我们创建一个新的 LoginActivity ,在 activity_login.xml 文件中:
有几个属性需要解释一下:
在 WelcomeFragment 中,点击登录和注册按钮可以分别跳转到 LoginFragment 和 RegisterFragment 中。
WelcomeFragment.
这里我使用了两种方式实现:
目标: 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 即可,这里不再出示代码。最后的效
果:
LoginFragment
目标: WelcomeFragment 通过 Safe Args 将数据传到 RegisterFragment , RegisterFragment 接收后显示。
再看一下已经展示过的 login_navigation.xml :
细心的可能已经观察到 navigation 目录下的 login_navigation.xml 资源文件中的 action 标签和 argument
标签,这里需要解释一下:
argument标签
点击Android studio中的Make Project按钮,可以发现系统为我们生成了两个类:
系统生成的类
WelcomeFragment
中的
JOIN US
按钮点击事件:
btnRegister.setOnClickListener {
val action = WelcomeFragmentDirections
.actionWelcomeToRegister()
.setEMAIL("[email protected]")
findNavController().navigate(action)
}
RegisterFragment 中的接收:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
val safeArgs:RegisterFragmentArgs by navArgs()
val email = safeArgs.email
mEmailEt.setText(email)
}
以及效果:
RegisterFragment
需要提及的是,如果不用
Safe Args
,
action
可以由
Navigation.createNavigateOnClickListener(R.id.next_action, null)
方式生成,感兴趣的可以自行编写。
Navigation 可以绑定 menus 、 drawers 和 bottom navigation ,这里我们以 bottom navigation 为例,我先在
navigation 目录下新创建了 main_navigation.xml ,接着新建了 MainActivity ,下面则是
activity_main.xml :
MainActivity 中的处理也十分简单:
class MainActivity : AppCompatActivity() {
lateinit var bottomNavigationView: BottomNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
//...
val host: NavHostFragment =
supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
val navController = host.navController
initWidget()
initBottomNavigationView(bottomNavigationView,navController)
}
private fun initBottomNavigationView(bottomNavigationView: BottomNavigationView, navController: NavController) {
bottomNavigationView.setupWithNavController(navController)
}
private fun initWidget() {
bottomNavigationView = findViewById(R.id.navigation_view)
}
}
效果:
我建立了一个编程资料共享学习Q裙:裙号是793544421,也可直接添加我的唯心:【Keaiduoooo_】。我整理了一系列编程学习视频、Android技术原理、手写源码、架构思维、书籍、笔记等等,需要文中资料的同学,进群即可获得。【技术学习交流,广告勿入】,技术是有边界的,但是学习是无界的,群里会有一些大神帮忙解答,有时你闷头想一天,不如别人的三言两语就醍醐灌顶。