前言
🏀什么是 Navigation?官方文档的话有点不容易让人理解。所以,这里用我自己的话来总结一下,我们在处理 Fragment 是需要通过写 Fragment 的事务去操作 Fragment 的,而 Navigation 的出现是为了解决我们之前开发的一些痛点。Navigation 主要用于实现 Fragment 代替 Activity 的页面导航功能,让 Fragment 能够轻松的实现跳转与传递参数,我们可以通过使用 Navigation,让 Fragment 代替 android 项目中绝大多数的 Activity。但需要注意的是在使用 Navigation 切换页面生命周期的变化情况,避免开发过程中踩坑。
🌟官方文档:https://developer.android.google.cn/jetpack/androidx/releases/navigation
🌟navigation 项目地址:https://github.com/googlecodelabs/android-navigation
💡本文 Demo 地址:https://github.com/taxze6/Jetpack_learn/tree/main/Jetpack_basic_learn/navigation
使用 Navigation 具有什么优势?
处理 Fragment 事务
默认情况下,能正确处理往返操作
为动画和转换提供标准化资源
实现和处理深层链接
包括导航界面模式,例如抽屉式导航栏和底部导航,我们只需要完成少量的代码编写
Safe Args - 可在目标之间导航和传递数据时提供类型安全的 Gradle 插件
ViewModel 支持 - 您可以将 ViewModel 的范围限定为导航图,以在图标的目标之间共享与界面相关的数据
如何使用 Navigation 呢?
Navigation 目前仅 AndroidStudio 3.2 以上版本支持,如果您的版本不足 3.2,请点此下载最新版 AndroidStudio(2202 年了应该没有人还在用 3.2 以下的版本吧!🐤)
在开始学习Navigation组件之前,我们需要先对Navigation主要组成部分有个简单的了解,Navigation 由三部分组成:
Navigation graph:一个包含所有导航相关信息的 XML 资源
NavHostFragment:一种特殊的Fragment,用于承载导航内容的容器
NavController:管理应用导航的对象,实现Fragment之间的跳转等操作
下面我们正式开始学习 Navigation 啦
第一步:添加依赖
//project的Navigation依赖设置dependencies { //文章发布时的最新稳定版本: def nav_version = "2.4.2" // 使用java作为开发语言添加下面两行: implementation "androidx.navigation:navigation-fragment:$nav_version" implementation "androidx.navigation:navigation-ui:$nav_version" // Kotlin: implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version"}//Compose版本:implementation "androidx.navigation:navigation-compose:$nav_version"
复制代码
第二步:创建导航图
①右键点击res目录,然后依次选择New→ Android Resource Directory。此时系统会显示 New Resource Directory对话框。Directory name输入你的文件夹名(一般为navigation),Resource type选择navigation
②右键navigation文件夹,然后new →Navigation Resource File在File name中输入名称(常用 nav_graph_main 或 nav_graph)
第三步:创建 Fragment
为了让跳转更加的丰富,我们这里创建三个Fragment✔
我们可以自己手动创建:
FirstFragment:
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FirstFragment"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="hello world" /></FrameLayout>
复制代码
class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_first, container, false) }}
复制代码
另外创建两个和FirstFragement一样的:SecondFragment,ThirdFragment
我们也可以通过Navigation graph创建
我们在新建好的nav_graph_main.xml下,在右上角切换到Design模式,然后在Navigation Editor中,点击Create new destination,选择所需要的Fragment后,点击Finish,你就会发现Fragment已经出现在我们可以拖动的面板中了。
第四步:将 Fragment 拖入面板并进行跳转配置
只需要在Navigation Editor中双击想要的Fragment就会被加入到面板中啦。
点击其中一个Fragment,你会发现,在他的右边会有一个小圆点,拖曳小圆点指向想要跳转的那个Fragment,我们这里设置FirstFragment → SecondFragment → ThirdFragment → FirstFragment
我们将nav_graph_main.xml切换到Code下,我们来解读一下xml
<?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/nav_graph_main" app:startDestination="@id/firstFragment"> <fragment android:id="@+id/firstFragment" android:name="com.taxze.jetpack.navigation.FirstFragment" android:label="fragment_first" tools:layout="@layout/fragment_first" > <action android:id="@+id/action_firstFragment_to_secondFragment2" app:destination="@id/secondFragment" /> </fragment> <fragment android:id="@+id/secondFragment" android:name="com.taxze.jetpack.navigation.SecondFragment" android:label="fragment_second" tools:layout="@layout/fragment_second" > <action android:id="@+id/action_secondFragment_to_thirdFragment2" app:destination="@id/thirdFragment" /> </fragment> <fragment android:id="@+id/thirdFragment" android:name="com.taxze.jetpack.navigation.ThirdFragment" android:label="fragment_third" tools:layout="@layout/fragment_third" > <action android:id="@+id/action_thirdFragment_to_firstFragment" app:destination="@id/firstFragment" /> </fragment></navigation>
复制代码
💡注意:在 fragment 标签下的 android:name 属性,其中的包名的是否正确声明
第五步:处理 MainActivity
①编辑MainActivity的布局文件,在布局文件中添加NavHostFragment。我们需要告诉Navigation和Activity,我们的Fragment展示在哪里,所以NavHostFragment其实就是导航界面的容器
<?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=".MainActivity"> <fragment android:id="@+id/nav_host_fragment" android:layout_width="0dp" android:layout_height="0dp" android:name="androidx.navigation.fragment.NavHostFragment" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph_main" /></androidx.constraintlayout.widget.ConstraintLayout>
复制代码
fragment标签下的android:name是用于指定NavHostFragment
app:navGraph是用于指定导航视图的
app:defaultNavHost=true是在每一次Fragment切换时,将点击记录在堆栈中保存起来,在需要退出时,按下返回键后,会从堆栈拿到上一次的Fragment进行显示。但是在某些情况下,这样的操作不是很友好,不过好在我们只需要将app:defaultNavHost=true改为app:defaultNavHost=false或者删除这行即可。在其为false的情况下,无论怎么切换Fragment,再点击返回键就都直接退出app。当然我们也可以对其堆栈进行监听,从而来实现,点击一次返回键回到主页,再点击一次返回键退出app。
②修改MainActivity
我们重写了onSupportNavigateUp,表示我们将Activity的back点击事件委托出去
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } override fun onSupportNavigateUp(): Boolean { return findNavController(R.id.nav_host_fragment).navigateUp() }}
复制代码
第六步:处理 Fragment 的对应跳转事件
①Fragment布局:给一个按钮用于跳转,一个TextView用于标识,三个Fragment布局相同
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FirstFragment"> <Button android:id="@+id/firstButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="点击跳转到第二个fragment" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="@string/hello_first_fragment" /></FrameLayout>//secondFragment中加入:<Button android:id="@+id/firstButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="点击跳转到第三个fragment" />//thirdFragment中加入:<Button android:id="@+id/firstButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="返回第一个fragment" />
复制代码
②配置 Fragment 对应的跳转事件
class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_first, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) view.findViewById<Button>(R.id.firstButton).apply { setOnClickListener { it.findNavController().navigate(R.id.action_firstFragment_to_secondFragment2) } } }}//secondFragment中加入:override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) view.findViewById<Button>(R.id.firstButton).apply { setOnClickListener { it.findNavController().navigate(R.id.action_secondFragment_to_thirdFragment2) } }}//thirdFragment中加入:override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) view.findViewById<Button>(R.id.firstButton).apply { setOnClickListener { it.findNavController().navigate(R.id.action_thirdFragment_to_firstFragment) } }}
复制代码
其中的R.id.action_firstFragment_to_secondFragment2这样的标识,是在nav_graph_main.xml的action标签下配置的。
<action android:id="@+id/action_firstFragment_to_secondFragment2" app:destination="@id/secondFragment" />
复制代码
③最后的效果图:
跳转动画 &自定义动画
我们会发现,刚刚的例子中,我们在跳转界面时,没有左滑右滑进入界面的动画,显得很生硬,所以我们要给跳转过程中添加上动画。
①添加默认动画:
在nav_graph_main.xml文件中的Design模式下,点击连接两个Fragment的线。然后你会发现在右侧会出现一个Animations的面板,然后我们点击enterAnim这些选项最右侧的椭圆点,然后就会弹出Pick a Resoure的面板,我们可以在这里选择需要的动画,这里我们就设置nav_default_enter_anim。同理exitAnim我们也设置一个动画,nav_default_exit_anim。然后运行代码你就发现一个渐变的跳转动画。然后配置动画后会发现action多了动画相关的属性
<fragment android:id="@+id/firstFragment" android:name="com.taxze.jetpack.navigation.FirstFragment" android:label="fragment_first" tools:layout="@layout/fragment_first" > <action android:id="@+id/action_firstFragment_to_secondFragment2" app:destination="@id/secondFragment" app:enterAnim="@anim/nav_default_enter_anim" app:exitAnim="@anim/nav_default_exit_anim" /></fragment>
复制代码
enterAnim: 跳转时的目标页面动画
exitAnim: 跳转时的原页面动画
popEnterAnim: 回退时的目标页面动画
popExitAnim:回退时的原页面动画
②自定义动画
💡 在真正的业务需求中是会有很多不同的跳转动画的,官方提供的默认动画是不够的,所以我们要学会自定义动画。
⑴创建 Animation 资源文件
右键点击res目录,然后依次选择New→ Android Resource File。此时系统会显示 New Resource File对话框。File name输入你的文件夹名(这里设置为slide_from_left),Resource type选择Animation,然后我们就可以发下在res目录下多了一个anim目录,里面存放着我们自定义的动画。
⑵编写我们的动画代码
这里举几个常用的例子:
//左滑效果<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="300" android:fromXDelta="-100%" android:toXDelta="0%"> </translate></set>
复制代码
//右滑效果<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="300" android:fromXDelta="0%" android:toXDelta="100%"> </translate></set>
复制代码
//旋转效果<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:duration="1000" android:fromXScale="0.0" android:fromYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:toXScale="1.0" android:toYScale="1.0" /> <rotate android:duration="1000" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" /></set>
复制代码
常用的属性:
常用设置:
⑶使用自定义动画文件
使用自定义动画也是和使用默认动画是一样的。
旋转效果:
如何传递数据?
💡Navigation 支持您通过定义目的地参数将数据附加到导航操作。一般情况下,建议传递少量数据。例如传递 userId,而不是具体用户的信息。如果需要传递大量的数据,还是推荐使用 ViewModel。
在nav_graph_main.xml文件中的Design模式下。点击选中其中的Fragment。在右侧的Attributes 面板中,点击Arguments选项右侧的加号。添加需要的参数。添加参数后,在箭头 Action 上点击,会在右边的 Argument Default Values中显示这个userId变量,在 xml 中也可以看到
//伪代码,请勿直接cv<fragment ... > ... <argument android:name="userId" android:defaultValue="1" app:argType="integer" /></fragment>
复制代码
代码处理:
//默认将 箭头 Action 中设置的参数传递过去it.findNavController().navigate(R.id.action_firstFragment_to_secondFragment2)
复制代码
动态传递数据
①我们可以使用 Bundle 在目的地之间传递参数
//伪代码,请勿直接cvview.findViewById<Button>(R.id.firstButton).setOnClickListener { val bundle = Bundle() bundle.putString("userId", "1") val navController = it.findNavController() navController.navigate(R.id.action_firstFragment_to_secondFragment2, bundle)}
复制代码
②然后我们就可以接受参数啦
在对应的 Fragment:
val tv = view.findViewById<TextView>(R.id.textView)tv.text = arguments?.getString("userId")
复制代码
在 Activity 使用 setGraph 切换不同的 Navigation
通常情况下,我们不止一个navigation的文件,我们需要根据业务情况去判断使用哪个,这里就可以用到我们的setGraph去切换不同的Navigation了。
①把activity_main中fragment标签下的app:navGraph这个属性去除
<fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:defaultNavHost="true"/>
复制代码
②在代码中通过setGraph设置app:navGraph
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initNav(1) } private fun initNav(id: Int) { var controller = Navigation.findNavController(this@MainActivity, R.id.nav_host_fragment) if (id == 1) { //设置对应的app:navGraph controller.setGraph(R.navigation.first) } if (id == 2) { controller.setGraph(R.navigation.second) } this@MainActivity.finish() }}
复制代码
到此,我们已经讲完了Navigation大部分的使用情况,下面来讲解几个重要的点,并通过一个案例来学习总结这篇文章吧。
NavController
💡 我们在前面已经讲了Navigation的使用,在处理Fragment的对应跳转事件时,我们用到了findNavController这个方法,其实呢,这个就是Navigation的三部分中的NavController中的一个api。那么什么是NavController呢?它是负责操作Navigation框架下的Fragment的跳转与退出、动画、监听当前Fragment信息,当然这些是基本操作。因为除了在Fragment中调用,在实际情况中它也可以在 Activity 中调用。如果能灵活的使用它,它可以帮你实现任何形式的页面跳转,也可以使用TabLayout配合Navigation在主页进行分页设计。
如何获取NavController实例呢?
在前面的基础使用中我们也用到了。
//伪代码,请勿直接cv//activity://Activity.findNavController(viewId: Int)findNavController(R.id.nav_host_fragment).navigateUp()//Fragment://Fragment.findNavController()//View.findNavController()findNavController().navigate(R.id.action_thirdFragment_to_firstFragment)
复制代码
Navigation 常用操作:
①popBackStack 弹出 Fragment
现在我们从oneFragment跳转到secondFragment在到thirdFragment,然后我们想从thirdFragment回到secondFragment那儿就可以使用popBackStack
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ..... btn.setOnClickListener{ //弹出Fragment controller.popBackStack() }}
复制代码
②弹出到指定的 Fragment
也是使用popBackStack,这个方法可以实现清空中间导航栈堆的需求。
//xxxFragment弹出到指定的Fragment。//第二个参数的布尔值如果为true则表示我们参数一的Fragment一起弹出,意思就是如果是false就popBackStack到//xxxFragment,如果是true,就在xxxFragment在popBackStack()一次controller.popBackStack(xxxFragment,true)
复制代码
③navigateUp() 向上导航
findNavController(R.id.nav_host_fragment).navigateUp()
复制代码
navigateUp也是执行返回上一级Fragment的功能。和popBackStack功能一样。那么既然它存在肯定是有它特殊的地方的。navigateUp向上返回的功能其实也是调用popBackStack的。 但是,navigateUp的源码里多了一层判断,判断这个Navigation是否是最后一个Fragment。使用popBackStack()如果当前的返回栈是空的就会报错,因为栈是空的了,navigateUp()则不会,还是停留在当前界面。
④添加导航监听
val listener: NavController.OnDestinationChangedListener = object : OnDestinationChangedListener() { fun onDestinationChanged( controller: NavController, destination: NavDestination, @Nullable arguments: Bundle? ) { Log.d(TAG, "onDestinationChanged: id = ${destination.getId()}") } }//添加监听controller.addOnDestinationChangedListener(listener)//移除监听controller.removeOnDestinationChangedListener(listener)
复制代码
⑤获取当前导航目的地
使用getCurrentDestination可以获取当前导航的目的地
//获取val destination = controller.getCurrentDestination()Log.d(TAG, "onCreate: NavigatorName = ${destination.getNavigatorName()}")Log.d(TAG, "onCreate: id = ${destination.getId()}")Log.d(TAG, "onCreate: Parent = ${destination.getParent()}")
复制代码
⑥判断当前页面显示的 Fragment 是不是目标 Fragment
//可直接cvfun <F : Fragment> isActiveFragment(fragmentClass: Class<F>): Boolean { val navHostFragment = this.supportFragmentManager.fragments.first() as NavHostFragment navHostFragment.childFragmentManager.fragments.forEach { if (fragmentClass.isAssignableFrom(it.javaClass)) { return true } } return false}
复制代码
使用 Safe Args 确保类型安全
💡 通过上面的 NavController 我们就可以实现 fragment 之间的跳转,但是 Google 建议使用 Safe Args Gradle 插件实现。这个插件可以生成简单的对象和构建器类,这些类就可以在目的地之间进行安全的导航和参数的传递啦。
那么,该如何使用 Safe Args呢。
①在项目最外面的build.gradle中加入
//将其放在plugins{}之前buildscript { repositories { google() } dependencies { def nav_version = "2.4.2" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" }}
复制代码
②在app、module下的build.gradle加入
如需生成适用于 Java 模块或Java 和 Kotlin混合模块的Java语言代码
apply plugin: "androidx.navigation.safeargs"
复制代码
如需生成适用于 Kotlin独有的模块的Kotlin代码,请添加以下行:
apply plugin: "androidx.navigation.safeargs.kotlin"
复制代码
💡 要使用 Safe Args,必须在 gradle.properties 这个文件中加入
android.useAndroidX=true
android.enableJetifier=true
为了避免生成的类名和方法名过于复杂,需要对导航图进行调整,修改了 action 的 id,因为自动生成的 id 太长了,会导致插件生成的类名和方法名也很长。
//伪代码,请勿直接cv<fragment android:id="@+id/blankFragment" android:name="com.taxze.jetpack.navigation.BlankFragment" android:label="fragment_blank" tools:layout="@layout/fragment_blank" > <action android:id="@+id/toSecond" 修改此处id app:destination="@id/blankFragment2" /></fragment>
复制代码
然后就会为我们生成BlankFragment和BlankFragment2的类啦,然后就可以和上面一样使用,传递参数啦。
var action = BlankFragment.actionJump("111")
复制代码
也可以使用 set 方法对对应的参数进行赋值
通过 Navigation 模仿 WeChat 底部跳转
💡通过 Navigation 实现开发中超级常用的底部跳转功能
话不多说,先上效果图:
①右键点击res目录,然后依次选择New→ Android Resource File。此时系统会显示 New Resource File对话框。File name输入你的文件夹名(这里设置为menu),Resource type选择Menu,然后我们就可以发下在res目录下多了一个menu目录,里面存放着我们底部跳转的item。
②进入menu.xml的Design下
填入四个Item,并分别设置id,title,icon
③创建四个Fragment,并在Navigation中建立链接
Fragment 的布局十分简单,这里就放一个的代码。
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".HomeFragment"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Home" /></FrameLayout>
复制代码
class HomeFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_home, container, false) }}
复制代码
在nav_graph_main.xml建立连接,注意这里每个Fragment的id要和menu.xml中的id一一对应
④在activity_main中使用BottomNavigationView建立底部跳转
这里在drawable下创建一个selector_menu_text_color.xml用于区分当前的Item
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="#818181" android:state_checked="false"/> <item android:color="#45C01A" android:state_checked="true"/></selector>
复制代码
<?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=".MainActivity"> <fragment android:id="@+id/nav_host_fragment" android:layout_width="0dp" android:layout_height="0dp" android:name="androidx.navigation.fragment.NavHostFragment" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph_main" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/nav_view" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:itemIconTint="@drawable/selector_menu_text_color" app:labelVisibilityMode="labeled" app:itemTextColor="@drawable/selector_menu_text_color" app:menu="@menu/menu" /></androidx.constraintlayout.widget.ConstraintLayout>
复制代码
⑤在 MainActivty 中设置切换逻辑
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //去除标题栏 supportRequestWindowFeature(Window.FEATURE_NO_TITLE) setContentView(R.layout.activity_main) val navController: NavController = Navigation.findNavController(this, R.id.nav_host_fragment) val navigationView = findViewById<BottomNavigationView>(R.id.nav_view) NavigationUI.setupWithNavController(navigationView, navController) }}
复制代码
这样我们就可以实现效果图中的效果啦,具体代码可以查看Git仓库😉
尾述
这篇文章已经很详细的讲了 Jetpack Navigation 的大部分用法,不过在看完文章后,你仍需多多实践,相信你很快就可以掌握 Navigation 啦😺 因为我本人能力也有限,文章有不对的地方欢迎指出,有问题欢迎在评论区留言讨论~
关于我
Hello,我是 Taxze,如果您觉得文章对您有价值,希望您能给我的文章点个❤️,也欢迎关注我的博客。
如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章——万一哪天我进步了呢?😝
基础系列:
2022 · 让我带你Jetpack架构组件从入门到精通 — Lifecycle
学会使用LiveData和ViewModel,我相信会让你在写业务时变得轻松🌞
当你真的学会DataBinding后,你会发现“这玩意真香”!
Navigation — 这么好用的跳转管理框架你确定不来看看?(本文🌟)
以下部分还在码字,赶紧点个收藏吧🔥
2022 · 让我带你 Jetpack 架构组件从入门到精通 — Room
2022 · 让我带你 Jetpack 架构组件从入门到精通 — Paging3
2022 · 让我带你 Jetpack 架构组件从入门到精通 — WorkManager
2022 · 让我带你 Jetpack 架构组件从入门到精通 — ViewPager2
2022 · 让我带你 Jetpack 架构组件从入门到精通 — 登录注册页面实战(MVVM)
进阶系列:
协程 + Retrofit 网络请求状态封装
Room 缓存封装
.....
评论