Android Navigation + Fragment 制作APP主页面导航(步骤 + 源码

1. 添加依赖


Navigation 是JetPack中的组件,感兴趣可以去查看Google JetPack官方文档。而如果你想单独查看的Navigation 内容,可以点击Navigation 文档

打开你的app下的build.gradle。在dependencies闭包中添加如下依赖:

def nav_version = “2.3.2”

// navigation依赖 ui 和 fragment

implementation “androidx.navigation:navigation-fragment:$nav_version”

implementation “androidx.navigation:navigation-ui:$nav_version”

添加位置如下图所示:

在这里插入图片描述

添加好之后,点击Sync进行项目同步,同步时会自动下载这些依赖库并配置到你的项目中。

添加完了依赖,就得先来简单介绍一下这个Navigation了,Navigation分为三大件:导航图、NavHost、NavController。

为了方便我介绍下面的三个概念,这里假设有A、B、C三个Fragment。

现在要从A切换到B

导航图:读取这个切换目标及路径

NavHost:包含A、B、C的容器,用于显示Fragment。

NavController:在得知切换目标时,控制NavHost去显示B这个Fragment。

这么一说,你是否有一些理解了呢?

2. 添加导航图


鼠标右键点击resNewAndroid Resource File

在这里插入图片描述

然后会弹出一个窗体,在这个窗体里面设置文件名称,并选择文件类型,然后点击OK。

在这里插入图片描述

然后查看这个nav_graph.xml,你会发现有报错

在这里插入图片描述

不过先不用担心,因为这个里面是用来指向Fragment的,但是现在没有,那就创建。

然后先在com.llw.navigation下新建一个fragment包。

然后建一个Fragment类,这里命名我就用ABCDE来命名了,实际开发中是肯定不能这样的。

在这里插入图片描述

然后在layout新建一个布局fragment_a.xml

在这里插入图片描述

然后修改一下这个布局

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:gravity=“center”

android:orientation=“vertical”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“A Fragment”

android:textColor=“#000”

android:textSize=“24sp” />

布局有了,然后进入到AFragment中绑定这个布局的id。

public class AFragment extends Fragment {

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_a, container, false);

}

}

那么这个AFragment就弄好了,同样按照上面的步骤创建BCDE的Fragment,这个重复的步骤我就不写了,因为有注水的涉嫌。

注意之前fragment_a.xml中我放了一个TextView用来表示这个是A,那么其他的xml中也要放置对应的BCDE,这样你切换的时候才能看到区别。

好了,下面可以打开这个nav_graph.xml进行Fragment的添加,在navigation标签下增加对AFragment的添加。

<fragment

android:id=“@+id/afragment”

android:name=“com.llw.navigation.fragment.AFragment”

android:label=“afragment”

tools:layout=“@layout/fragment_a” />

上面的也很简单,id表示它在导航图的标识,name指明这个Fragment的路径,包名+类名。label就是标签而已。layout就是绑定这个Fragment对应的布局。

这里你肯定回想,刚才不是在AFragment的onCreateView方法的返回中指明这这个布局吗?

在这里插入图片描述

那么这里又添加是为什么,因为你如果在导航图中指明了某一个Fragment的布局,那么在代码中就可以不用指明,也可以两者都指明,但至少要有一个地方指明,所以我这样写是可以的。为了让看的人更了解而已,虽然是多此一举。

那么这个nav_graph.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”

xmlns:tools=“http://schemas.android.com/tools”

android:id=“@+id/nav_graph”>

<fragment

android:id=“@+id/afragment”

android:name=“com.llw.navigation.fragment.AFragment”

android:label=“afragment”

tools:layout=“@layout/fragment_a” />

<fragment

android:id=“@+id/bfragment”

android:name=“com.llw.navigation.fragment.BFragment”

android:label=“bfragment”

tools:layout=“@layout/fragment_b” />

<fragment

android:id=“@+id/cfragment”

android:name=“com.llw.navigation.fragment.CFragment”

android:label=“cfragment”

tools:layout=“@layout/fragment_c” />

<fragment

android:id=“@+id/dfragment”

android:name=“com.llw.navigation.fragment.DFragment”

android:label=“dfragment”

tools:layout=“@layout/fragment_d” />

<fragment

android:id=“@+id/efragment”

android:name=“com.llw.navigation.fragment.EFragment”

android:label=“efragment”

tools:layout=“@layout/fragment_e” />

然后你会发现还报错,那么你可以现在navigation标签中添加

tools:ignore=“UnusedNavigation”

在这里插入图片描述

它就不报错了,这句话的意思是未使用导航的许可。因为我现在还没有使用这个nav_graph.xml所以要加上这一句话告诉AS,让它放心。等我们真正去使用时,是没有影响的,去不去掉都行。

3. 添加NavHost


这个在上面是介绍过的,它是用来装载和显示Fragment的,都知道Fragment是要依附在Activity上的,那么很明显这个NavHost也是要放在Activity中,那么下面打开activity_main.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=“.MainActivity”>

<fragment

android:id=“@+id/nav_host_fragment”

android:name=“androidx.navigation.fragment.NavHostFragment”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

app:navGraph=“@navigation/nav_graph” />

</androidx.constraintlayout.widget.ConstraintLayout>

可能这里你会比较陌生,这里的id,等下要在MainActivity中指明的,这里的name指明的是androidx.navigation.fragment.NavHostFragment,这个属性就表明这个fragment指明的就是NavHost,然后它还要添加需要显示的子Fragment,那么就通过navGraph来绑定这个导航图,之前导航图里面不是就有五个Fragment吗?所以这样NavHost的任务就完成了。

但是这时候又有一个问题,那就是我的这个NavHost初始显示哪一个Fragment,这一点Google的人也想到了,可以在导航图中指明。

打开nav_graph.xml。通过startDestination来指明启动Activity时显示的第一个Fragment。

app:startDestination=“@id/afragment”

在这里插入图片描述

这里我指明了AFragment。那么值钱说到的三大件,就还差一个NavController。这个是用来控制NavHost显示Fragment,虽然我刚才在导航图nav_graph.xml中指明了第一个要显示的Fragment,但是它还缺少这个显示的动机,而这个动机由NavController来提供。

4. NavController控制显示Fragment


进入到MainActivity,在onCreate添加一句代码:

//获取navController

NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);

这时候你运行代码,然后你就会发现,显示了AFragment。

在这里插入图片描述

惊不惊喜意不意外?明明这个NavController还什么都没有做的,为什么就可以显示了呢?实际上它已经在工作了,只是你没有注意而已。

Navigation.findNavController(this, R.id.nav_host_fragment);

通过这一行代码这个工作开关就已经打开了,打开中读取导航图中第一个要显示Fragment,然后显示在NavHostFragment中。

5. Fragment之间跳转并传值


平时在实际的开发中常常会从一个Fragment跳转到另一个Fragment,并且带一些参数过去,之前这些跳转都是比较麻烦的,需要自己去写一些业务逻辑,而且还很容易出问题,让人谈之色变。但是在Navigation中,这个状况得到了很大的改善。

那么具体来看一下是怎么做的,比如我现在从AFragment跳转到BFragment。

下面就是见证骚操作的时候了。打开nav_graph.xml,修改AFragment。

<fragment

android:id=“@+id/afragment”

android:name=“com.llw.navigation.fragment.AFragment”

android:label=“afragment”

tools:layout=“@layout/fragment_a”>

<action

android:id=“@+id/action_afragment_to_bfragment”

app:destination=“@id/bfragment”

app:enterAnim=“@anim/nav_default_enter_anim”

app:exitAnim=“@anim/nav_default_exit_anim” />

这里又多了一个新的action标签,表示动作,id的命名要规范,从这个命名来看就知道要从A跳转到B。然后就是destination属性,它指明一个跳转到的Fragment。enterAnim表示进入BFragment的动画,exitAnim表示退出BFragment的动画,这些都是Navgation中自带的。

现在动作写好了,那么下面就需要一个地方来触发这个动作,可以写一个简单的按钮来触发。

在fragment_a.xml中修改布局如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:gravity=“center”

android:orientation=“vertical”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“A Fragment”

android:textColor=“#000”

android:textSize=“24sp” />

<Button

android:id=“@+id/jumpBFragment”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginTop=“20dp”

android:text=“跳转到 BFragment”

android:textAllCaps=“false”

android:textSize=“16sp” />

然后进入到AFragment中,绑定id,增加点击事件。代码如下:

package com.llw.navigation.fragment;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Button;

import androidx.annotation.NonNull;

import androidx.annotation.Nullable;

import androidx.fragment.app.Fragment;

import androidx.navigation.NavController;

import androidx.navigation.Navigation;

import com.llw.navigation.R;

public class AFragment extends Fragment {

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_a, container, false);

}

@Override

public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {

super.onViewCreated(view, savedInstanceState);

Button jumpBFragment = view.findViewById(R.id.jumpBFragment);

jumpBFragment.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Navigation.findNavController(getView())

//导航

.navigate(R.id.action_afragment_to_bfragment);

}

});

}

}

这里唯一不好理解的就是navigate,表示导航的意思,这里面我传入了刚才定义在nav_graph.xml中的action的id。就表示这个导航将要执行这个actiion,那么它就会跳转到BFragment。运行一下

在这里插入图片描述

很明显,跳过去了,不过感觉还少了点什么,因为平常Fragment之间跳转时都会传递参数过去,那么这个也要传参数,而Navigation也提供了这个功能,可以通过Bundle进行传参。

所以只要简单的修改这个点击的方法就可以了。

jumpBFragment.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Bundle bundle = new Bundle();

bundle.putString(“content”,“How are you?”);

Navigation.findNavController(getView())

//导航

.navigate(R.id.action_afragment_to_bfragment,bundle);

}

});

这种Bundle传递参数我相信都不会陌生,那么在BFragment怎么去接收呢?

打开BFragment,修改代码如下:

package com.llw.navigation.fragment;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Toast;

import androidx.annotation.NonNull;

import androidx.annotation.Nullable;

import androidx.fragment.app.Fragment;

import com.llw.navigation.R;

public class BFragment extends Fragment {

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

String content = getArguments().getString(“content”);

Toast.makeText(getActivity(),content,Toast.LENGTH_SHORT).show();

return inflater.inflate(R.layout.fragment_b, container, false);

}

}

这里通过

getArguments().getString(“content”);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

  • Android进阶学习全套手册
    关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。

  • Android高级架构师进阶知识体系图
    关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!

  • Android对标阿里P7学习视频

  • BATJ大厂Android高频面试题
    这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

-nhIpEpDf-1712065108666)]

最后

文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!

  • Android进阶学习全套手册
    关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。

[外链图片转存中…(img-a9R0WTMu-1712065108666)]

  • Android高级架构师进阶知识体系图
    关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
    [外链图片转存中…(img-mPqkR7xK-1712065108666)]

  • Android对标阿里P7学习视频

[外链图片转存中…(img-RiH09nps-1712065108667)]

  • BATJ大厂Android高频面试题
    这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
    [外链图片转存中…(img-UdWZm8K7-1712065108667)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 11
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值