Android Jetpack学习之旅--> Navigation 的使用
Posted Kevin-Dev
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Jetpack学习之旅--> Navigation 的使用相关的知识,希望对你有一定的参考价值。
简介
1. 定义
Navigation
是一个可简化 android
导航的库和插件;更确切的来说,Navigation
是用来管理 Fragment
的切换,并且可以通过可视化的方式,看见 App
的交互流程。这完美的契合了 Jake Wharton
大神单 Activity
的建议。
2. 优点
- 处理
Fragment
的切换 - 默认情况下正确处理
Fragment
的前进和后退 - 为过渡和动画提供标准化的资源
- 实现和处理深层连接
- 可以绑定
Toolbar
、BottomNavigationView
和ActionBar
等 SafeArgs
(Gradle插件) 数据传递时提供类型安全性ViewModel
支持
3. 前期准备
Android studio
版本需要 3.2+
4. 学习资料
- 谷歌官方教程:Navigation Codelab
- 谷歌官方文档:Navigation
- 官方 Demo:Demo地址
实践
0. 效果图
1. 添加依赖
在根目录的 build.gradle
添加:
buildscript
ext
kotlinVersion = '1.6.10'
appCompatVersion = "1.4.0"
recyclerVersion = "1.2.1"
materialVersion = "1.4.0"
navigationVersion = "2.3.5"
constraintLayoutVersion = "2.1.2"
dependencies
classpath 'com.android.tools.build:gradle:7.0.4'
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
在 app/build.gradle
添加:
plugins
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'androidx.navigation.safeargs.kotlin'
dependencies
...
//Navigation
implementation "androidx.navigation:navigation-fragment-ktx:$rootProject.navigationVersion"
implementation "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion"
2. 创建 navigation 导航
创建基础目录:资源文件 res
目录下创建 navigation
目录 -> 右击 navigation
目录 New
一个Navigation resource file
。
<?xml version="1.0" encoding="utf-8"?>
<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/login_navigation"
app:startDestination="@id/welcome">
<fragment
android:id="@+id/login"
android:name="com.hkt.navigationapp.LoginFragment"
android:label="LoginFragment"
tools:layout="@layout/login_fragment"
/>
<fragment
android:id="@+id/welcome"
android:name="com.hkt.navigationapp.WelcomeFragment"
android:label="LoginFragment"
tools:layout="@layout/welcome_fragment">
<action
android:id="@+id/action_welcome_to_login"
app:destination="@id/login"/>
<action
android:id="@+id/action_welcome_to_register"
app:enterAnim="@anim/common_slide_in_right"
app:exitAnim="@anim/common_slide_out_left"
app:popEnterAnim="@anim/common_slide_in_left"
app:popExitAnim="@anim/common_slide_out_right"
app:destination="@id/register"/>
</fragment>
<fragment
android:id="@+id/register"
android:name="com.hkt.navigationapp.RegisterFragment"
android:label="LoginFragment"
tools:layout="@layout/register_fragment"
>
<argument
android:name="EMAIL"
android:defaultValue="2005@qq.com"
app:argType="string"/>
</fragment>
</navigation>
创建一个 Destination
,如果说 navigation
是我们的导航工具,Destination
是我们的目的地,在此之前,我已经写好了一个 WelcomeFragment
、LoginFragment
和 RegisterFragment
,添加Destination
的操作完成后如下所示
3. 建立 NavHostFragment
我们创建一个新的 LoginActivity
,在 activity_login.xml
文件中:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
<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>
4. 界面跳转、参数传递和动画
在 WelcomeFragment
中,点击登录和注册按钮可以分别跳转到 LoginFragment
和RegisterFragment
中。
方式一 利用 ID 导航
目标:WelcomeFragment
携带 key
为 name
的数据跳转到 LoginFragment
,LoginFragment
接收后显示。
Have a account ? Login
按钮的点击事件如下:
btnLogin.setOnClickListener
// 设置动画参数
val navOption = navOptions
anim
enter = R.anim.common_slide_in_right
exit = R.anim.common_slide_out_left
popEnter = R.anim.common_slide_in_left
popExit = R.anim.common_slide_out_right
val name = AppPrefsUtils.getString(BaseConstant.SP_USER_NAME)
// Navigation 传递参数
val bundle = Bundle()
bundle.putString(BaseConstant.ARGS_NAME,name)
findNavController().navigate(R.id.login, bundle,navOption)
方式二 利用 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>
<fragment
android:id="@+id/register"
...
>
<argument
android:name="EMAIL"
android:defaultValue="2005@qq.com"
app:argType="string"/>
</fragment>
</navigation>
5. 更多
Navigation
可以绑定 menus
、drawers
和 bottom navigation
,这里我们以 bottom navigation
为例,我先在 navigation
目录下新创建了 main_navigation.xml
,接着新建了 MainActivity
,下面则是activity_main.xml
:
<LinearLayout
...>
<fragment
android: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.BottomNavigationView
android: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: 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)
效果:
小结
以上是关于Android Jetpack学习之旅--> Navigation 的使用的主要内容,如果未能解决你的问题,请参考以下文章
Android Jetpack 学习之旅--> Data Binding 的使用
Android Jetpack学习之旅--> Navigation 的使用
Android Jetpack 学习之旅--> ViewModel & LiveData 的使用
Android Jetpack 学习之旅--> Room 的使用