Android--Jetpack--Navigation详解

须知少日拏云志,曾许人间第一流

一,定义

Navigation 翻译成中文就是导航的意思。它是谷歌推出的Jetpack的一员,其目的主要就是来管理页面的切换和导航。

Activity 嵌套多个 Fragment 的 UI 架构模式已经非常普遍,但是对 Fragment 的管理,我们一般通过 FragmentManager 和 FragmentTransaction 来管理 Fragment 之间的切换。页面的切换通常还包括对应用程序 App bar 的管理、Fragment 间的切换动画,以及 Fragment 间的参数传递。纯代码的方式使用起来不是特别友好,并且 Fragment 和 App bar 在管理和使用的过程中显得混乱。

使用Navigation可以很方便的管理和切换Fragment。

二,角色介绍

Navigation组件由三部分构成:

1)导航图(xml文件)包含所有导航相关信息的 XML 资源,其中包含所有目的地和操作。该图表会显示应用的所有导航路径。

2)NavHostFragment导航宿主是 Navigation 组件的核心部分之一。导航宿主是一个空容器,用户在应用中导航时,目的地会在该容器中交换进出。

3)NavController导航到目的地是使用NavController 完成的,它是一个在NavHost中管理应用导航的对象。每个NavHost均有自己的相应NavController 。

三,Navigation的优点

1)可视化的页面导航图,类似于 Apple Xcode 中的 StoryBoard,便于我们理清页面关系。

2)通过 destination 和 action 完成页面间的导航。

 3)方便添加页面切换动画。

 4)页面间类型安全的参数传递。

 5)通过 NavigationUI,对菜单、底部导航、抽屉菜单导航进行统一的管理。

四,基本使用

1,在app的build.gradle中添加引用:

implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'

2,在res目录下创建导航图(xml文件):

 

 点击ok就会生成xml文件

3,创建fragment:

创建三个fragment,分别为YZ1Fragment,YZ2Fragment,YZ3Fragment

public class YZ1Fragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_yz1,container,false);}}

fragment_yz1:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"android:background="#223355"><TextViewandroid:id="@+id/message"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="我是第一页"android:textSize="20sp"android:textStyle="bold"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="跳转第二页"android:textAllCaps="false"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@+id/message" /></androidx.constraintlayout.widget.ConstraintLayout>
public class YZ2Fragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_yz2,container,false);}
}

fragment_yz2:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"android:background="#dd2233"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="16dp"android:text="第二页"android:textSize="20sp"android:textStyle="bold"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:text="返回第一页"android:textAllCaps="false"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/textView" /><Buttonandroid:id="@+id/btn2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:text="前往第三页"android:textAllCaps="false"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn" /></androidx.constraintlayout.widget.ConstraintLayout>
public class YZ3Fragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_yz3,container,false);}
}

fragment_yz3:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"android:background="#33ff22"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="16dp"android:text="第三页"android:textSize="20sp"android:textStyle="bold"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:text="跳到第二页"android:textAllCaps="false"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/textView" /></androidx.constraintlayout.widget.ConstraintLayout>

4,回到yuanzhen_nav.xml中,点击添加:

添加三个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"android:id="@+id/yuanzhen_nav"app:startDestination="@id/YZ1Fragment"><fragmentandroid:id="@+id/YZ1Fragment"android:name="com.yuanzhen.mynavigation.YZ1Fragment"android:label="YZ1Fragment" ><actionandroid:id="@+id/action_YZ1Fragment_to_YZ2Fragment2"app:destination="@id/YZ2Fragment" /></fragment><fragmentandroid:id="@+id/YZ2Fragment"android:name="com.yuanzhen.mynavigation.YZ2Fragment"android:label="YZ2Fragment" ><actionandroid:id="@+id/action_YZ2Fragment_to_YZ3Fragment2"app:destination="@id/YZ3Fragment" /><actionandroid:id="@+id/action_YZ2Fragment_to_YZ1Fragment2"app:destination="@id/YZ1Fragment" /></fragment><fragmentandroid:id="@+id/YZ3Fragment"android:name="com.yuanzhen.mynavigation.YZ3Fragment"android:label="YZ3Fragment" ><actionandroid:id="@+id/action_YZ3Fragment_to_YZ2Fragment2"app:destination="@id/YZ2Fragment" /></fragment>
</navigation>

这里的action代表的就是跳转路径。

5,在fragment中实现跳转代码:

public class YZ1Fragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_yz1,container,false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);Button btn=view.findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Navigation.findNavController(view).navigate(R.id.action_YZ1Fragment_to_YZ2Fragment2);}});}}
public class YZ2Fragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_yz2,container,false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);Button btn=view.findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Navigation.findNavController(view).navigate(R.id.action_YZ2Fragment_to_YZ1Fragment2);}});Button btn2=view.findViewById(R.id.btn2);btn2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Navigation.findNavController(view).navigate(R.id.action_YZ2Fragment_to_YZ3Fragment2);}});}
}
public class YZ3Fragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_yz3,container,false);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);Button btn=view.findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Navigation.findNavController(view).navigate(R.id.action_YZ3Fragment_to_YZ2Fragment2);}});}}

6,在Activity添加fragment:

public class MainActivity extends AppCompatActivity {private NavController navController;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);navController = Navigation.findNavController(this, R.id.frag);NavigationUI.setupActionBarWithNavController(this, navController);}}

activity_main:

<?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"><fragmentandroid:id="@+id/frag"android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true"android:name="androidx.navigation.fragment.NavHostFragment"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/yuanzhen_nav"/></androidx.constraintlayout.widget.ConstraintLayout>

运行效果:

 五,添加导航栏

1,在res目录下添加menu:

2,menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/YZ1Fragment"android:icon="@mipmap/pic_article_default"android:title="首页"/><itemandroid:id="@+id/YZ2Fragment"android:icon="@mipmap/tell_normal"android:title="第二页"/><itemandroid:id="@+id/YZ3Fragment"android:icon="@mipmap/video_call_default"android:title="第三页"/>
</menu>

注意,这里的id就是你要跳转的fragment名称

3,在activity_main添加新的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:orientation="vertical"><fragmentandroid:id="@+id/frag"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="9"app:defaultNavHost="true"android:name="androidx.navigation.fragment.NavHostFragment"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/yuanzhen_nav"/><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/btm"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"app:menu="@menu/menu"/></LinearLayout>

4,在MainActivity添加代码:

public class MainActivity extends AppCompatActivity {private NavController navController;BottomNavigationView bottomNavigationView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bottomNavigationView=findViewById(R.id.btm);navController = Navigation.findNavController(this, R.id.frag);NavigationUI.setupWithNavController(bottomNavigationView,navController);}
}

实现效果:

 六,添加动画效果

添加动画效果非常简单:

1,打开yuanzhen_nav.xml文件

2,点击试图的跳转线:

3, 

有四个动画可以选择

选择之后yaunzhen_nav文件如下:

<?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"android:id="@+id/yuanzhen_nav"app:startDestination="@id/YZ1Fragment"><fragmentandroid:id="@+id/YZ1Fragment"android:name="com.yuanzhen.mynavigation.YZ1Fragment"android:label="YZ1Fragment" ><actionandroid:id="@+id/action_YZ1Fragment_to_YZ2Fragment2"app:destination="@id/YZ2Fragment"app:enterAnim="@anim/nav_default_pop_enter_anim"app:exitAnim="@anim/nav_default_pop_enter_anim"app:popEnterAnim="@anim/nav_default_pop_exit_anim"app:popExitAnim="@anim/nav_default_pop_exit_anim" /></fragment><fragmentandroid:id="@+id/YZ2Fragment"android:name="com.yuanzhen.mynavigation.YZ2Fragment"android:label="YZ2Fragment" ><actionandroid:id="@+id/action_YZ2Fragment_to_YZ3Fragment2"app:destination="@id/YZ3Fragment"app:enterAnim="@anim/nav_default_enter_anim"app:exitAnim="@anim/nav_default_exit_anim"app:popEnterAnim="@anim/nav_default_enter_anim"app:popExitAnim="@anim/nav_default_pop_exit_anim" /><actionandroid:id="@+id/action_YZ2Fragment_to_YZ1Fragment2"app:destination="@id/YZ1Fragment" /></fragment><fragmentandroid:id="@+id/YZ3Fragment"android:name="com.yuanzhen.mynavigation.YZ3Fragment"android:label="YZ3Fragment" ><actionandroid:id="@+id/action_YZ3Fragment_to_YZ2Fragment2"app:destination="@id/YZ2Fragment" /></fragment>
</navigation>

也可以自己去自定义动画

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222750.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sql标准梳理

SQL&#xff08;Structured Query Language&#xff09;是一种用于管理关系型数据库管理系统&#xff08;RDBMS&#xff09;的标准化语言。SQL标准由国际标准化组织&#xff08;ISO&#xff09;和美国国家标准化组织&#xff08;ANSI&#xff09;制定和维护&#xff0c;旨在提供…

SpringIOC之FilterType

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

spring 笔记六 SpringMVC 获得请求数据

文章目录 SpringMVC 获得请求数据获得请求参数获得基本类型参数获得POJO类型参数获得数组类型参数获得集合类型参数请求数据乱码问题参数绑定注解requestParam获得Restful风格的参数获得Restful风格的参数自定义类型转换器获得Servlet相关API获得请求头RequestHeaderCookieValu…

js解析.shp文件

效果图 原理与源码 本文采用的是shapefile.js工具 这里是他的npm地址 https://www.npmjs.com/package/shapefile 这是他的unpkg地址&#xff0c;可以点开查看源码 https://unpkg.com/shapefile0.6.6/dist/shapefile.js 这个最关键的核心问题是如何用这个工具&#xff0c;网上…

Vue3-18-侦听器watch()、watchEffect() 的基本使用

什么是侦听器 个人理解&#xff1a;当有一个响应式状态&#xff08;普通变量 or 一个响应式对象&#xff09;发生改变时&#xff0c;我们希望监听到这个改变&#xff0c;并且能够进行一些逻辑处理。那么侦听器就是来帮助我们实现这个功能的。侦听器 其实就是两个函数&#xff…

〖大前端 - 基础入门三大核心之JS篇(54)〗- 原型和原型链

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

曹操出行集成:无代码API连接广告推广与用户运营

曹操出行集成的必要性 随着科技的不断进步&#xff0c;无代码API集成已经成为企业提升效率、优化营销策略的重要手段。对于新能源汽车共享服务领导者曹操出行而言&#xff0c;将其服务集成至企业营销系统中&#xff0c;不仅可以提升客户体验&#xff0c;还能加强品牌的市场竞争…

微信小程序 全局共享数据 mobx

前言 全局数据共享&#xff08;又叫做&#xff1a;状态管理&#xff09;是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有&#xff1a;Vuex、Redux、MobX 等。 一. 安装 npm install --save mobx-miniprogram4.13.2 mobx-miniprogram-bindings2.1.5 安装完…

基于主动安全的AIGC数据安全建设

面对AIGC带来的数据安全新问题&#xff0c;是不是就应该一刀切禁止AIGC的研究利用呢&#xff1f;答案是否定的。要发展AIGC&#xff0c;也要主动积极地对AIGC的数据安全进行建设。让AIGC更加安全、可靠的为用户服务。为达到此目的&#xff0c;应该从三个方面来开展AIGC的数据安…

【WebRTC】用WebRTC做即时视频聊天应用

【配套项目源码】 打开即用,设置一个免费的Agora账户就可以实现视频电话。非常好的WebRTC学习和应用项目。 用VSCode打开即可。 https://download.csdn.net/download/weixin_41697242/88630069 【什么是WebRTC?】 WebRTC是一套基于JS的API,能够建立端对端的直接通信,实…

后端接口开发-web前台请求接口对后台数据库增删改查-实例

一、后端接口开发的逻辑是&#xff1a; 1.Application项目启动 2.前台接口Url请求后台 3.Controller控制拿到前台请求参数&#xff0c;传递给中间组件Service 4.Service调用Mapper.java 5. mapper.java映射到mapper.xml中的mybatis语句&#xff0c;类似Sql语句操作数据库 6.其…

GDPU 数据结构 天码行空14

实验十四 查找算法的实现 一、【实验目的】 1、掌握顺序排序&#xff0c;二叉排序树的基本概念 2、掌握顺序排序&#xff0c;二叉排序树的基本算法&#xff08;查找算法、插入算法、删除算法&#xff09; 3、理解并掌握二叉排序数查找的平均查找长度。 二、【实验内容】 …

群晖(Synology)云备份的方案是什么

群晖云备份方案就是在本地的 NAS 如果出现问题&#xff0c;或者必须需要重做整列的时候&#xff0c;保证数据不丢失。 当然&#xff0c;这些是针对有价值的数据&#xff0c;如果只是电影或者不是自己的拍摄素材文件&#xff0c;其实可以不使用云备份方案&#xff0c;因为毕竟云…

Ubuntu如何安装KVM

环境&#xff1a; 联想E14笔记本 Ubuntu20.04 问题描述&#xff1a; Ubuntu如何安装KVM 解决方案&#xff1a; 1.验证CPU是否支持硬件虚拟化 rootst-ThinkPad-E14:~# grep -Eoc (vmx|svm) /proc/cpuinfo 162.检查 VT 是否在 BIOS 中启用 安装 apt install cpu-checker …

stm32F407-GPIO的使用——点亮LED并且讲解各个寄存器

stm32F407-GPIO的使用——点亮LED并且讲解各个寄存器 本文为stm32GPIO的介绍与使用&#xff0c;例子是简单的LED点亮。 一、 GPIO GPIO&#xff08;General Purpose I/O Ports&#xff09;意思为通用输入/输出端口&#xff0c;通俗地说&#xff0c; 就是一些引脚&#xff0c;可…

AGI魔盒,会放出冥王PLUTO还是阿童木?

人机共生&#xff0c;是科幻作品永恒的主题。其中&#xff0c;《冥王PLUTO》可能是最早探讨人类与机器人如何在冲突中共存的漫画作品。 如果说阿童木是人机共生的“和平使者”&#xff0c;启蒙了几代人对机器人的信任和热爱,那么冥王PLUTO就是阿童木的反面&#xff0c;一个心怀…

基于ssm网络安全宣传网站设计论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网络安全宣传网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

2023-12-14 使用Qt画一条曲线(AI辅助)

点击 <C 语言编程核心突破> 快速C语言入门 使用Qt画一条曲线 前言一、Qchart简介二、代码总结 前言 要解决问题: 有一个函数, 生成一些点, 想画一条曲线. 想到的思路: 这个用Qchart比较简单. 其它的补充: 需要稍许配置 一、Qchart简介 QChart是Qt中的一个图表控件&a…

记录 | mac打开终端时报错:login: /opt/homebrew/bin/zsh: No such file or directory [进程已完成]

mac打开终端时报错&#xff1a;login: /opt/homebrew/bin/zsh: No such file or directory [进程已完成]&#xff0c;导致终端没有办法使用的情况 说明 zsh 没有安装或者是安装路径不对 可以看看 /bin 下有没有 zsh&#xff0c;若没有&#xff0c;肯定是有 bash 那就把终端默…

三层交换机原理与配置

文章目录 三层交换机原理与配置一、三层交换技术概述二、传统的 MLS三、基于CEF 的MLS1、转发信息库&#xff08;FIB&#xff09;2、邻接关系表3、工作原理&#xff1a; 四、三层交换机的配置1、三层交换机配置命令2、三层交换机配置步骤 三层交换机原理与配置 一、三层交换技…