Android实战开发--底部导航(Fragment)篇

2023-05-16

安卓实战开发之底部导航

提示:本篇文中对基本的操作不做细节讲解,后续会通过链接方式跳转到对应的知识点。


文章目录

  • 安卓实战开发之底部导航
  • 前言
  • 一、准备
    • 1、矢量图标准备
    • 2、文件准备
  • 二、使用步骤
    • 1.在fragment中动态加载布局
    • 2.构建导航框架
    • 3、初始化控件
    • 4、 给FrameLayout添加默认布局
    • 5、实例化一个View.OnClickListener对象来写一个点击事件
    • 6、给控件设置写好的点击事件
  • 三、 总结


前言

本片文章将使用Fragment来构建底部导航。底部导航栏我们使用矢量图标(png/jpg等也可以,其中优劣自行体会),这里我们通过Android Stdio 自带的矢量图标下载功能进行下载。


一、准备


1、矢量图标准备

  • 通过New——>Vector Asset,点击Clip Art打开图标的搜索界面。注意搜索时是需要联网的,且通过英文搜索。比如像常用的首页图标,我们这里输入“home”。
  • 选择完之后,点击OK,设置图片属性,Next选择资源文件位置(main),最终会保存到res资源目录的drawable目录下
    图标生成
  • 下载后是一个xml文件,我们可以更改它的颜色和宽高。这里我们将同一个图标设置拷贝成两份颜色不同的图标,用作选中(蓝色)和未选中(灰色)使用
  • 这里我们总共准备了五个选中图标、五个未选中图标

    在这里插入图片描述

2、文件准备

  • 有五个图标我们就需要五个Fragment文件>
    在这里插入图片描述
  • 最后再准备一个底部导航的布局文件,这里的底部导航是一个独立的布局,我们是通过include(包含)来引入这个底部导航的布局的。(布局自行构建这里不做讲解)
    在这里插入图片描述

注意:这里需要设置默认图标,和默认文字颜色都设为未选中的颜色(第一个图标和文字控件设置为选中状态)


二、使用步骤

1.在fragment中动态加载布局

  • 继承Fragment

代码如下(示例):

public class HomeFragment extends Fragment {

}
  • 通过快捷键(CTRL + O)快速生成onCreateView和onViewCreate方法。

代码如下(示例):

	//onCreateView的意思是:创建视图。
	//我们在这个方法里来动态加载布局
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		
	    return inflater.inflate(R.layout.fragment_home, container, false);
	}
	//onViewCreate的意思是:视图创建
	//我们在这个方法里面操作视图控件、逻辑方法就像是Activity的onCreate方法。
	//但是要注意我们操作的控件的时候使用的是:onCreateView返回view,通过传递实参到onViewCreated方法的形参View中,所以在初始化控件的时候是view.findViewById();
	//最后要注意如果有些方法使用不了,大概是因为那些方法实在Actiivty中(未作具体了解),所以需要先调用getActivity()方法。
	@Override
	public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
	    super.onViewCreated(view, savedInstanceState);
}

onCreateView方法分析:

一、首先我们可以看到这个方法的返回值类型为View(视图),所以我们需要创建View对象加载视图然后返回
    1、动态加载视图的写法:首先需要实例化LayoutInflater对象
    	LayoutInflater layoutInflater = getLayoutInflater();
    	View view = layoutInflater.inflate(R.layout.fragment,container,false);
    2、我们可以通过快捷键(CTRL + P)来查看inflate的参数列表(@LayoutRes int resource,ViewGroup root,boolean attachToRoot)
    	从字面意思来分析:
    	a.@LayoutRes int resource
    		第一个参数是一个@LayoutRes int类型的参数,通多CTRL + 左击查看@LayoutRes注解,我们可以通过注释知道这个整数参数返回的是一个布局资源引用(即R.layout.资源名)
    	b.ViewGroup root
    		第二个参数是一个ViewGroup(视图组),相当于一个容器,我们可以将若干个控件或布局放进去组成一个大的布局。root(根,底部的意思)看到这个单词我们通常会联想到权限,我们也可以理解为:我们引入的布局只在这个视图组内生效。
    	c.boolean attachToRoot
    		第三个参数是布尔类型,attachToRoot(附加到根),这里我们不附加到根(false),如果填的是附加(true)就会报错。原因和方案可以参考这个博主的文章:https://blog.csdn.net/yaolingrui/article/details/7339913

二、这里我们可以看到在onCreateView方法里面有LayoutInflater对象和ViewGroup对象,所以既然有意思和明显就是要你使用参数列表里面传过来的实参
三、最完整的写法是:View view = layoutInflater.inflate(R.layout.fragment,container,false);		这里我们就简写了


2.构建导航框架

  • 在activity_main.xml中引入导航的布局

代码如下(示例):

	<!--通过layout这个属性来添加写好的底部导航布局-->
	<include
	    android:id="@+id/include"
	    layout="@layout/navigation"
	    android:layout_width="match_parent"
	    android:layout_height="50dp"
	    app:layout_constraintBottom_toBottomOf="parent"
	    app:layout_constraintEnd_toEndOf="parent" />
  • 添加FrameLayout布局管理器

代码如下(示例):

	<FrameLayout
	   android:id="@+id/framelayout"
	   android:layout_width="match_parent"
	   android:layout_height="wrap_content"
	   tools:ignore="MissingConstraints" />
  • 我们可以嵌套一个滑动组件ScrollView包裹FrameLayout,注意引入的导航布局include不要嵌套进去,不然底部导航也会被滑动(那就不能算是底部导航了,懂我意思吧)

代码如下(示例):

<ScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent">

    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:ignore="MissingConstraints" />

</ScrollView>
  • 效果

    在这里插入图片描述

3、初始化控件

  • 在MainActivity.java中初始化控件

代码如下(示例):

//全局变量

//底部导航图片控件声明
 private ImageView[] imageViews;
    private int[] imageViewsId = {
            R.id.imageView01,
            R.id.imageView02,
            R.id.imageView03,
            R.id.imageView04,
            R.id.imageView05,
    };
//底部导航文字控件声明
    private TextView[] textViews;
    private int[] textViewsId = {
            R.id.textView01,
            R.id.textView02,
            R.id.textView03,
            R.id.textView04,
            R.id.textView05
    };
    
    //五个Fragment布局声明
    private Fragment[] fragments = {
      new HomeFragment(),
      new ServiceFragment(),
      new PartyFragment(),
      new NewsFragment(),
      new PersionFragment()
    };
  • 我们使用数组的方式声明,所有可以通过数组遍历来赋值:
//声明数组
imageViews = new ImageView[imageViewsId.length];
textViews = new TextView[textViewsId.length];

//初始化
for (int i = 0; i < imageViewsId.length; i++) {
    imageViews[i] = findViewById(imageViewsId[i]);
    textViews[i] = findViewById(textViewsId[i]);
}

4、 给FrameLayout添加默认布局

//这里需要注意的是getSupportFragment()方法
//还有一个getFragment()方法,这两方法等效
//区别在一所属包不同。第一个是在androidx中,第二个是在android中。
//所以要注意这里的我们之前准备的Fragment是继承自哪个包的Fragment,根据那个包选择方法,否则会报错
getSupportFragmentManager().beginTransaction().replace(R.id.framelayout,new HomeFragment()).commit();

5、实例化一个View.OnClickListener对象来写一个点击事件

        View.OnClickListener onClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                for (int i = 0; i < 5; i++) {
                    if(view.getId() == imageViewsId[i]) {
                        //替换布局
                        getSupportFragmentManager().beginTransaction().replace(R.id.framelayout, fragments[i]).commitAllowingStateLoss();
                        //设置图标文字状态
                        imageViews[i].setImageDrawable(getDrawable(drawablesTrue[i]));
                        textViews[i].setTextColor(getResources().getColor(R.color.text_true));
                    }else{
                        imageViews[i].setImageDrawable(getDrawable(drawablesFalse[i]));
                        textViews[i].setTextColor(getResources().getColor(R.color.text_false));
                    }
                }

            }
        };

注意:这里在调用图标资源的时候使用getDrawable()方法,但是在调用颜色资源的时候得先调用getResources()再调用getColor()方法,否则会报错。

分析:这个View.OnClickListener对象需要重写onClick方法,在onClick方法里会传入一个View对象的实参,这个对象实质上就是设置点击事件的控件。所以view.getId()方法实质上就是获取这个控件的id值,就是R.id.imageView01。

R.id.imageView01是一个@IdRes int类型的数据,本质上就是一串特定的数字。

6、给控件设置写好的点击事件

 for (int i = 0,j = 0; i < imageViewsId.length; i++,j++) {
            imageViews[i].setOnClickListener(onClickListener);
            textView[i].setOnClickListener(onClickListener);
        }

三、 总结

至此,底部导航完成。如有问题欢迎留言评论~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android实战开发--底部导航(Fragment)篇 的相关文章

  • 解决warning: incompatible implicit declaration of built-in function 'malloc'

    由于代码中使用了malloc函数和字符串函数 xff0c 编译时出现错误 warning incompatible implicit declaration of built in function malloc warning incom
  • 解决虚拟机安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题

    在Intel i5 4460的主机上安装Ubuntu 14 04 xff08 64位 xff09 xff0c 虚拟机使用的是Vmware 10 0 0 build 1295980 在新建好虚拟机 xff0c 运行时候就出现了VMware W
  • 【CentOS7】yum安装时出现错误Errno 14 Couldn't resolve host的解决办法

    在安装python sphinx时出现Errno 14 Couldn 39 t resolve host xff0c 什么东东 xff1f root 64 localhost jansson 1 2 yum install python s
  • SAS (Serial Attached SCSI) 技术详解

    xff08 一 xff09 什么是SAS SAS xff08 Serial Attached SCSI xff09 即串行SCSI技术 xff0c 是一种磁盘连接技术 xff0c 它综合了并行SCSI和串行连接技术 xff08 如FC SS
  • mdadm命令解析

    mdadm命令解析 一 在linux系统中目前以MD Multiple Devices 虚拟块设备的方式实现软件RAID 利用多个底层的块设备虚拟出一个新的虚拟设备 并且利用条带化 stripping 技术将数据块均匀分布到多个磁盘上来提高
  • fio使用指南

    这个文档是对fio 2 0 9 HOWTO文档的翻译 xff0c fio的参数太多了 xff0c 翻译这个文档时并没有测试每一个参数的功能和使用方法 xff0c 只有少量参数做了试验 xff0c 大部分的参数采用的是根据字面翻译或是个人理解
  • CentOS系统安装VNC详细步骤

    下面是总结的详细配置步骤 xff0c 分享给大家 一 VNC 远程控制 CentOS 系统 1 查看 CentOS 系统中是否有安装 vnc xff08 默认安装 xff09 输入命令 xff1a rpm q vnc vnc server
  • 怎么看电脑CPU是几核?

    对硬件的东西知之甚少 xff0c 保存在此 xff0c 以便以后查阅 方法一 鼠标右键桌面最下方的任务栏 任务管理器 性能 查看cpu使用记录 xff0c 有几个窗口就是几核心cpu xff1b 方法二 右键 我的电脑 属性 硬件 设备管理
  • linux批量远程控制

    前提 xff1a 勉ssh秘钥登陆 使用pdssh 1 配置主机列表 web list root 64 192 168 1 2 22 root 64 192 168 1 3 182 22 root 64 192 168 1 4 181 22
  • DataBinding详解

    一 开启DataBinding 在build gradle文件添加 android dataBinding enabled true 二 生成DataBinding布局 1 光标在布局文件的根布局 gt 点击Alt 43 Enter gt
  • python批量删除txt文件中指定行

    应用场景 xff1a 在深度学习项目中 xff0c 常常会处理各种数据集 比如已经标注好的数据标签有三类 xff1a 人形 汽车 猫 xff0c 有一个新项目 xff0c 只需要识别人形 xff0c 那就需要把这个数据集进行处理 xff0c
  • Python.循环

    一 循环结构 xff1a 是程序控制流程的三大结构之一 xff08 三大手段 方法之一 xff09 通过指定的条件将循环体进行有限次或无限次 xff08 死循环 xff09 地重复运行 在Python中主要用到while和for函数实现 二
  • bind详细学习

    DNS DNS xff1a Domain Name Service 应用层协议 xff08 C S 53 udp 53 tcp xff09 域名 分类 xff1a 最多可以有127级域名 根域一级域名 xff1a Top Level Dom
  • C++ 指针常量、常量指针和常指针常量

    1 指针常量 如果在定义指针变量时候 xff0c 指针变量前用const修饰 xff0c 被定义的指针变量就变成了一个指针类型的常变量 xff0c 指针类型的常变量简称为指针常量 格式如下 数据类型 const 指针变量 61 变量名 xf
  • Jetpack初尝试 NavController,LiveData,DataBing,ViewModel,Paging

    文章目录 插件配置NavController 使用1 创建xml2 创建Activity3 res 创建navigation nav garden和说明流程 ViewModel 负责页面的数据LiveData onChangedObserv
  • 移动固态硬盘删除分区(包括EFI分区)

    新换电脑原始的固态硬盘大小是500G xff0c 担心不够用 xff0c 但电脑只有一个放置固态硬盘的位置 xff0c 所以打算将原装的500G固态换成1T固态 xff0c 原始500G固态改成移动固态硬盘 原始500G固态一共有4个分区
  • Linux-OneNote的安装和使用

    P3X OneNote是Linux的非官方应用程序 xff0c 允许用户直接从Linux平台创建和共享笔记 安装 第一种方法 xff1a Snap安装 此部分转载自链接 在Linux操作系统上使用非官方版OneNote最快捷 最简单的方法是
  • Visual Studio运行控制台程序一闪而退的解决方法!

    初学者在使用Visual Studio各个版本时 xff0c 在进行调试运行时 xff0c 会发现控制台总是一闪即退 xff0c 输出结果的窗口无法保持打开状态 xff01 其实问题是你执行时按的是F5还是Ctrl 43 F5 xff0c
  • C# Microsoft.ClearScript.V8脚本使用

    1 ClearScript支持的功能和适用场景 微软的 net是非常强大和灵活的 xff0c 除了C 体系脚本扩展 xff0c 也支持其他流行的脚本扩展 xff0c Microsoft ClearScript V8就是一个 NET绑定到Go
  • WSL2中使用systemctl报错Failed to connect to bus: Host is down

    问题截图 xff1a System has not been booted with systemd as init system PID 1 Can t operate Failed to connect to bus Host is d

随机推荐