先上效果图:

Navigation组件,也可以理解成FragmentNavigation。它提供了多Fragment之间的转场栈管理,帮助我们可以更轻松的使用Fragment。在抽屉式导航栏、底部导航栏、顶部导航栏的需求中我们可以尝试使用这个新组件。甚至,可以尝试写一个单Activity的应用

Navigation

导航组件由以下三个关键部分组成:

  • Navigation视图:在res/navigation包下面的xml视图资源,包括应用内所有单个内容区域以及用户可以通过应用获取的可能路径。
  • NavHost:显示导航图中目的地的空白容器。导航组件包含一个NavHost实现(NavHostFragment),可显示Fragment目标
  • NacController:在NavHost中管理应用导航的对象。当用户在整个应用中移动时,NavController会安排NavHost中目标内容切换。

添加依赖

dependencies {def nav_version = "2.3.0"// Java language implementationimplementation "androidx.navigation:navigation-fragment:$nav_version"implementation "androidx.navigation:navigation-ui:$nav_version"// Kotlinimplementation "androidx.navigation:navigation-fragment-ktx:$nav_version"implementation "androidx.navigation:navigation-ui-ktx:$nav_version"// Dynamic Feature Module Supportimplementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"// Testing NavigationandroidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
}

创建导航视图

选择res / New / Android Resource File

点击ok之后,android studio 会自动帮我们在res文件夹下创建一个navigation目录,目录下面有一个刚刚创建的nav_graph.xml导航视图。导航视图中包含应用中各个目的地,即应用中用户可以导航到的任意位置。

接下来我们编辑导航视图,首先创建几个目的地Fragment:AFragment、BFragment、DFragment、EFragment、FFragment

这里我们创建了几个目的地Fragment,以及它们之间的跳转

<?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"app:startDestination="@id/mainFragment"><fragmentandroid:id="@+id/mainFragment"android:name="com.business.navigationdemo.ui.main.MainFragment"android:label="main_fragment"tools:layout="@layout/main_fragment"><actionandroid:id="@+id/action_mainFragment_to_AFragment"app:destination="@id/AFragment" /><actionandroid:id="@+id/action_mainFragment_to_BFragment"app:destination="@id/BFragment" /></fragment><fragmentandroid:id="@+id/AFragment"android:name="com.business.navigationdemo.ui.a.AFragment"android:label="AFragment"tools:layout="@layout/a_fragment"><actionandroid:id="@+id/action_AFragment_to_DFragment"app:destination="@id/DFragment" /></fragment><fragmentandroid:id="@+id/BFragment"android:name="com.business.navigationdemo.ui.b.BFragment"android:label="BFragment"tools:layout="@layout/b_fragment"><actionandroid:id="@+id/action_BFragment_to_EFragment"app:destination="@id/EFragment" /></fragment><fragmentandroid:id="@+id/DFragment"android:name="com.business.navigationdemo.ui.d.DFragment"android:label="DFragment"tools:layout="@layout/d_fragment"><actionandroid:id="@+id/action_DFragment_to_mainFragment"app:destination="@id/mainFragment"app:popUpTo="@id/mainFragment"app:popUpToInclusive="true" /></fragment><fragmentandroid:id="@+id/EFragment"android:name="com.business.navigationdemo.ui.e.EFragment"android:label="EFragment"tools:layout="@layout/e_fragment"><actionandroid:id="@+id/action_EFragment_to_FFragment"app:destination="@id/FFragment" /></fragment><fragmentandroid:id="@+id/FFragment"android:name="com.business.navigationdemo.ui.f.FFragment"android:label="FFragment"tools:layout="@layout/f_fragment"><actionandroid:id="@+id/action_FFragment_to_BFragment"app:destination="@id/BFragment"app:popUpTo="@id/BFragment"app:popUpToInclusive="true" /></fragment>
</navigation>

<navigation>元素时导航视图的根元素,当向图表中添加目的地和连接操作时,可以看到相应的<action>元素在这里显示为子元素。

当DFragment回退到MainFragment和FFragment回退到BFragment时,都添加了app:popUpto="",这样在导航过程中会从堆栈中移除它们中间的Fragment,利用app:popUpToInclusive="true",会将第一个MainFragment和第一个BFragment从堆栈中弹出并清除。如果不是使用app:popUpToInclusive="true",则堆栈中会包含两个目的地的实例。

添加导航宿主

NavHost即导航宿主,是Navigation组件的核心部分。导航宿主是一个空容器,用户在应用中导航时,目的地会在该容器中交换进出。导航宿主必须派生于NavHost。Navigation组件的默认NavHost实现(NavHostFragment)负责处理Fragment目的的交换。

注意:Navigation组件旨在用于具有一个主Activity和多个Fragment目的地的应用。主Activity与导航视图相关联,且包含一个负责根据需要交换目的地的NavHostFragment。在具有多个Activity目的地应用中,每个Activity都拥有其自己的导航图。

打开main_activity.xml文件,以在Layout Editor中打开,在Palette窗口内搜索“Nav”

<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"><fragmentandroid:id="@+id/nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="0dp"android:layout_height="0dp"app:defaultNavHost="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

接下来我们看一下MainActivity.kt的代码

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.main_activity)}override fun onSupportNavigateUp(): Boolean {val fragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment)return if (fragment != null) {NavHostFragment.findNavController(fragment).navigateUp()} else {super.onSupportNavigateUp()}}
}

这里重写onSupportNavigationUp()方法,目的时将back时间委托出去。若堆栈中由两个以上Fragment,点击back键就会返回到上一个Fragment。

MainFragment.kt如下:

class MainFragment : Fragment() {companion object {fun newInstance() = MainFragment()}private val viewModel by lazy { ViewModelProviders.of(this).get(MainViewModel::class.java) }override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View {return inflater.inflate(R.layout.main_fragment, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val btnNextA = view.findViewById<Button>(R.id.btn_next_A)val btnNextB = view.findViewById<Button>(R.id.btn_next_B)btnNextA.setOnClickListener { v ->Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_AFragment)}btnNextB.setOnClickListener { v ->Navigation.findNavController(v).navigate(R.id.action_mainFragment_to_BFragment)}}}

AFragment.kt

class AFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.a_fragment, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val btnNextD = view.findViewById<Button>(R.id.btn_next_D);btnNextD.setOnClickListener { v ->//官方推荐使用Safe Args的插件用于导航的数据传递//也可以使用Bundle的方式val bundle = bundleOf("AA" to "Hello", "BB" to " World")Navigation.findNavController(v).navigate(R.id.action_AFragment_to_DFragment, bundle);}}
}

DFragment.kt

class DFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.d_fragment, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val tvInfo = view.findViewById<TextView>(R.id.tv_info)val btnBackToMain = view.findViewById<Button>(R.id.btn_back_main)tvInfo.text = "${arguments?.getString("AA")} ${arguments?.getString("BB")}"btnBackToMain.setOnClickListener { v ->Navigation.findNavController(v).navigate(R.id.action_DFragment_to_mainFragment)}}
}

FFragment.kt

class FFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.f_fragment, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val btnBackToB = view.findViewById<Button>(R.id.btn_back_B)val btnBack = view.findViewById<Button>(R.id.btn_back)btnBack.setOnClickListener { v ->Navigation.findNavController(v).navigateUp()}btnBackToB.setOnClickListener { v ->Navigation.findNavController(v).navigate(R.id.action_FFragment_to_BFragment)}}
}

我们运行看一效果:

BottomNavigationView

我们直接创建一个BottomNavigationView工程

Android Studio会自动帮我们创建导航视图并添加导航宿主

<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/navigation_home"android:icon="@drawable/ic_home_black_24dp"android:title="@string/title_home" /><itemandroid:id="@+id/navigation_dashboard"android:icon="@drawable/ic_dashboard_black_24dp"android:title="@string/title_dashboard" /><itemandroid:id="@+id/navigation_notifications"android:icon="@drawable/ic_notifications_black_24dp"android:title="@string/title_notifications" /></menu>

res/menu文件下多了一个bottom_nav_menu.xml的文件,这里定义了底部导航栏的图标文字等信息

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingTop="?attr/actionBarSize"><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/nav_view"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginStart="0dp"android:layout_marginEnd="0dp"android:background="?android:attr/windowBackground"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:menu="@menu/bottom_nav_menu" /><fragmentandroid:id="@+id/nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true"app:layout_constraintBottom_toTopOf="@id/nav_view"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/mobile_navigation" /></androidx.constraintlayout.widget.ConstraintLayout>

activity_main.xml中自动帮我们定义了BottomNavigationView,并指定了底部导航的menu,以及导航的宿主。

至此,我们可以看到,利用Navigation,我们可以非常轻松的处理Fragment的跳转、回退、转场动画。这几乎跟Activity一模一样了。有了它,我们完全可以实现一个单个Activity的App了。

项目地址:https://github.com/Claire6649/BottomNavigationDemo

Android Jetpack 学习之Navigation、BottomNavigationView相关推荐

  1. Android Jetpack组件之Navigation使用-源码

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

  2. Android Jetpack导航组件——Navigation的使用

    概述 Navigation是采用一个Activity和多个Fragment形式设计的Ui架构模式,但是众所周知,Fragment的管理一直是个麻烦事,需要通过FragmentManager和Fragm ...

  3. 【Android Jetpack学习之旅】--> Navigation 的使用

    不断学习,做更好的自己!

  4. Android JetPack底部导航Navigation 组件的介绍与使用

    1.介绍: 在以前的应用中,针对多导航模块的使用,常见的有tabhost或者FragmentTabHost,但是这些在使用的过程中,非常臃肿,包括加载和管理也不如人意.在AndroidX中,官方引入N ...

  5. 现学现用Android Jetpack - Navigation

    前言 即学即用Android Jetpack系列Blog的目的是通过学习Android Jetpack完成一个简单的Demo,本文是即学即用Android Jetpack系列Blog的第一篇. 记得去 ...

  6. Android 官方架构组件 Navigation 使用详解

    前言 前段时间,我在做项目开发的时候对Fragment的管理遇到几个小问题,总觉得在现阶段封装好的Fragment管理器不太优雅.这成为我下决心学习Jetpack在很早之前推出的Navigation库 ...

  7. Android Jetpack从入门到精通(深度好文,值得收藏)

    前言 即学即用Android Jetpack系列Blog的目的是通过学习Android Jetpack完成一个简单的Demo,本文是即学即用Android Jetpack系列Blog的第一篇. 记得去 ...

  8. Android Jetpack组件之Hilt使用

    前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. And ...

  9. Android Jetpack组件App Startup简析

    1.前言 最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面. A ...

最新文章

  1. 2015级C++第14周实践项目 模板
  2. R二项分布检验:双尾二项检验(Two-tailed Binomial Test)、左尾二项检验(Left-tailed Binomial Test)、右尾二项检验
  3. 深度学习基础(基本概念、优化算法、初始化、正则化等)
  4. 一文读懂计算计仿真技术
  5. 【Linux入门到精通系列讲解】工具——make/Makefile
  6. 路由器的修改权限密码、还原出厂设置、备份配置文件和升级操作系统实际操作...
  7. npm 安装出错 npm ERR! request to https://registry.npmjs.org/express failed, reason: unable to verify th
  8. lr_save_var() 截取任意字符串长度,以参数形式输出(参数转变量)
  9. vue中动画效果的实现
  10. 云计算学习一——网络基础
  11. 【实验报告】LFM信号产生与频谱分析(记录一次实验:《电类综合实验》)
  12. 韩顺平 Java集合 自学笔记(Java30天基础)
  13. SQL Server基础知识
  14. 保持初心,不负韶华||回顾2021,展望2022
  15. 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)
  16. spring redis executePipelined
  17. java 文件传输 多客户端 传输多文件_java 文件传输 多客户端 传输多文件
  18. 软件过程和项目管理(CMMI配置管理)
  19. 计算机应用期刊主编终审通过率,审稿快的期刊_最容易发表审稿快的学报_审稿快的三本或大专学报...
  20. UI设计师都能做什么,UI设计都有哪几个职业方向

热门文章

  1. 前备 正点原子以及野火stm32资料获取
  2. C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度
  3. jzoj 2867. 【集训队互测 2012】Contra
  4. 心理学实验学习pygame编程-贪吃蛇(2)
  5. 使用python绘制有效性前沿
  6. 论文解读:PF磷酸:基于机器学习的磷酸化位点预测疟原虫蛋白的工具
  7. 如何运行Python程序?
  8. mt4支持python么_mt4 python
  9. sql数据库连接:用户‘sa’登录失败问题破解(百度加个人总结)
  10. 海思3559编译live555