【Android】BottomNavigationView+ViewPager实现底部导航栏(步骤+源码)

2023-11-03

吐糟大会

时隔好久再一次在博客上与大家见面,上一年九月份怀疑自己不适合这行毅然辞职。我没结婚没车贷没房贷本以为能很潇洒,但现实给我开了个玩笑,我发现除了这一行其他什么都不会,也许是我很懒吧。为了能吃饱饭我再次踏入这一行。回归初衷为了让更多刚入行的小白饱受各种烂博客的折磨,我一切从简跟随我的步伐一步一步敲出属于自己的技术。

效果浏览

咳咳咳,博客不支持模拟器录制的视频抱歉了各位,我描述一下吧。
点击导航切换fragment,滑动也可以切换fragment并且底部导航会对应上。
额外还有一个fragment跳转传值的功能。

为了区分开将第二个背景色弄成了黑色 其他两个是白色。

正文

Activity + Fragment + TabLayout + ViewPager
Activity + Fragment + RadioGroup(RadioButton) + ViewPager
这两种是以前普遍的写法 但是呢 这种写法过于麻烦,而现在又出来了一种省时省力的方法
我们今天的主角 BottomNavigationView+ViewPager+Fragment

第一步

第二步

activity_main.xml
<RelativeLayout 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">
    
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_views"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:labelVisibilityMode="labeled"
        android:layout_alignParentBottom="true"
        app:itemIconTint="@drawable/menu_item_selected"
        app:itemTextColor="@drawable/menu_item_selected"
        app:menu="@menu/bottom_nav_menu" >
    </com.google.android.material.bottomnavigation.BottomNavigationView>

</RelativeLayout>

itemIconTint和itemTextColor分别表示图标和文字


右键点击drawable然后新建一个menu_item_selected.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#888888" android:state_checked="false" />
    <item android:color="#1296DB" android:state_checked="true" />
</selector>

bottom_nav_menu

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/home"
        android:orderInCategory="0"
        android:title="@string/title_home" >
    </item>

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ca"
        android:orderInCategory="1"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/na"
        android:orderInCategory="2"
        android:title="@string/title_notifications" />

</menu>
里面有三个menu分别对应三个底部导航也就是Fragment

第三步

创建三个Fragment,这时就可以将项目跑起来你会发现已经有轮廓了只是没有滑动和点击功能。

第四步

    private BottomNavigationView navigationView;
    public ViewPager viewPager;
    //初始化三个Fragment
    private HomeFragment fragment_home = new HomeFragment();
    private DashboardFragment fragment_dashboard = new DashboardFragment();
    private NotificationsFragment fragment_notifications = new NotificationsFragment();
    private MyFragmentPagerAdapter myFragmentPagerAdapter;
    private long lastBackPressedTime = 0;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager = findViewById(R.id.viewPager);
        viewPager.addOnPageChangeListener(this);//监听viewPager页面变化
        navigationView = findViewById(R.id.nav_views);
        navigationView.setOnNavigationItemSelectedListener(this);//监听NaView的变化
        myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
        //设置设配器 专门写了个内部类进行绑定  因为后面myFragmentPagerAdapter 还有用
        viewPager.setAdapter(myFragmentPagerAdapter);
        // 将ViewPager默认选中第二个Fragment 
        // 注意:最后这两行代码设置到setAdapter之前是没用的
        viewPager.setCurrentItem(1);
       // 更新BottomNavigationView的选中状态
        navigationView.getMenu().getItem(1).setChecked(true);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        navigationView.getMenu().getItem(position).setChecked(true);
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
        //这三个id对应的是menu里面三个item的Id
            case R.id.navigation_home:
                //对应Id设置对应选中
                viewPager.setCurrentItem(0);
                return true;
            case R.id.navigation_dashboard:
                viewPager.setCurrentItem(1);
                return true;
            case R.id.navigation_notifications:
                viewPager.setCurrentItem(2);
                return true;
            default:
                return false;
        }

    }

    public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
        public MyFragmentPagerAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        @Override
        public int getCount() {
            return 3;
        }

        @Override
        public Fragment getItem(int position) {
        //这里的012对应的是Fragment的排序
            switch (position) {
                case 0:
                    return fragment_home;
                case 1:
                    return fragment_dashboard;
                case 2:
                    return fragment_notifications;
            }
            return null;
        }
    }


     //该方法是为了Fragment跳转传值的中转
    public void onFragmentInteraction(String value){
        DashboardFragment secondFragment = (DashboardFragment) myFragmentPagerAdapter.instantiateItem(viewPager, 1);
        if (secondFragment != null) {
            secondFragment.updateValue(value);
        }
    }

    @Override
    public void onBackPressed() {
        if (System.currentTimeMillis() - lastBackPressedTime < 3000) {
            super.onBackPressed();
        } else {
            lastBackPressedTime = System.currentTimeMillis();
            Toast.makeText(this, "再按一次退出应用", Toast.LENGTH_SHORT).show();
        }
    }

到了这里呢,我们的效果就已经完成了。这里呢是赠送了一个点击下面展示Fragment间的跳转传值。

Fragment跳转传值第一步

HomeFragmen跳转到DashboardFragment
  @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_home,container,false);

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button button=view.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String value = "Hello from FirstFragment";
                ((MainActivity) requireActivity()).viewPager.setCurrentItem(1);
                ((MainActivity) requireActivity()).onFragmentInteraction(value);
            }
        });
    }
简简单单一个按钮点击设置选中第二个Fragment 然后调用Activity的onFragmentInteraction方法中转。
  public void onFragmentInteraction(String value){
          //获取要跳转的Fragment
        DashboardFragment secondFragment = (DashboardFragment) myFragmentPagerAdapter.instantiateItem(viewPager, 1);
        //调用Fragment的方法进行传值
        if (secondFragment != null) {
            secondFragment.updateValue(value);
        }
    }
DashboardFragment

    public void updateValue(String value) {
        Toast.makeText(getActivity(), ""+value, Toast.LENGTH_SHORT).show();
    }
到这里呢今天的内容就结束了,相对来说挺简单的。不过呢写这篇文章的时候我本来想用另外一种方法去写导航栏 然后发现那个作者没加ViewPager我加进去试了试发现不行有点问题没搞定,所以用了这个方案。 那个方案相对全面一点,我这个方案比较简便。参考文章:Android Navigation + Fragment 制作APP主页面导航(步骤 + 源码) 这个唯一的缺点就是没加ViewPager。可惜我也加不上 嘿嘿 不过也够用了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Android】BottomNavigationView+ViewPager实现底部导航栏(步骤+源码) 的相关文章

随机推荐

  • Eladmin框架前端后台学习笔记

    文章目录 Eladmin框架前端后台学习 项目简介 用户账号密码 运行 技术栈 项目结构 常见问题 1 如何开发一个新模块 2 如何做权限管理 3 头部增删改查等按钮 不显示某个按钮 或从左侧或右侧新增按钮 4 页面初始化时不请求查询数据接
  • Golang 单元测试框架的使用

    一 使用gomonkey stub 打桩 在测试包中创建一个模拟方法 用于替换生成代码中的方法 1 stub函数 gomonkey ApplyFunc target double 其中target是被mock的目标函数 double是用户重
  • 文件上传骚姿势合集

    目录 黑名单规则绕过 绕过前端 js 检测方法 判断是否为前端检测还是后端服务器检测方法 绕过 contnet type 检测上传 常见MIME类型 绕过黑名单上传 同解析后缀名 htaccess 重写解析绕过上传 大小写绕过上传 空格绕过
  • http、https流程以及版本区别

    从输入url后按下回车开始 因为可能记录了地址 看是否要redirect 因为可能记录了永久跳转成新的地址 再看缓存 没有缓存再去服务器 首先查找DNS 创建TCP连接 发送http请求数据包 返回响应数据 结束接受返回 http 0 9
  • Spark 流数据处理简介

    一 Spark 基础知识 1 1 Spark 简介 Spark是专为大规模数据处理而设计的快速通用的计算引擎 可用它来完成各种各样的运算 包括 SQL 查询 文本处理 机器学习等 1 2 核心概念介绍 Spark常用术语介绍 Applica
  • HTTP报头

    HTTP协议是什么 HTTP协议 HyperText Transfer Protocol 超文本传输协议 是用于从WWW服务器传输超文本到本地浏览器的传送协议 它可以使浏览器更加高效 使网络传输减少 它不仅保证计算机正确快速地传输超文本文档
  • 一篇文章入门Hibernate框架

    什么是Hibernate 一个框架 一个Java领域的持久化框架 一个ORM框架 什么叫持久化操作 和数据库相关的各种操作 对象的增删改查 什么是ORM 对象 关系映射 ORM思想 将关系数据块中表中的记录映射成为对象 以对象的形式展现 程
  • 525中电六所智能

    还是要记录一下 总结反思学习一下的 0 面试官自我介绍 1 自我介绍 2 介绍项目 有了解过视频流嘛 视频流是指视频数据的传输 例如 它能够被作为一个稳定的和连续的流通过网络处理 因为流动 客户机浏览器或插件能够在整个文件被传输完成前显示多
  • 数据库系统概论 中文高清PDF版下载

    数据库系统概论 中文高清PDF版下载 转载于 https www cnblogs com gavinhughhu archive 2010 01 05 1639949 html
  • 等保测评2.0_三级——【安全计算环境】MySQL数据库测评项汇总

    等保测评2 0 三级 安全计算环境 MySQL数据库测评项汇总 安全计算环境 MySQL数据库测评项汇总 五个测评单元 控制项 1 身份鉴别 a 应对登录的用户进行身份标识和鉴别 身份标识具有唯一性 身份鉴别信息具有复杂度要求并定期更换 b
  • Ngnix:防止恶意域名解析

    通过nginx部署的网站 默认没有设置主机头 可以通过IP或其他未在配置文件中指定的域名来访问 这有可能会导致恶意域名指向到我们服务器IP地址 而根据工信部备案系统判定原则 如有非法域名恶意指向用户主机并且网站访问状态为未有效关闭 则此类非
  • ubuntu 下安装Valgrind 内存泄漏检查工具

    Valgrind 安装 1 到www valgrind org下载最新版valgrind 3 7 0 tar bz2 2 解压安装包 tar jxvf valgrind 3 7 0 tar bz2 3 解压后生成目录valgrind 3 7
  • 【超快捷】Windows系统自带的快捷键合集

    总览 一 常用 Win E 打开我的电脑 Win R 打开 运行 对话框 Win L 锁定计算机 Ctrl Shift Esc 打开任务管理器 Ctrl Alt Delete 打开安全窗口 F2 重命名文件 F5 刷新当前页面或者桌面 Al
  • ERP让员工和企业双赢

    企业的科学管理 离不开数字化 而数字化 就需要企业积累数据 这就离不开ERP ERP实施 如果只是员工增加了数据录入量 而没有获得实际的益处 比如 效率提高 难度降低等 则员工内心会抵制ERP 员工要的是方便 企业要的是数据 必须兼顾二者
  • 快速理解聚集索引和非聚集索引

    数据库的索引 听起来挺神秘的 仔细想想 这些索引 其实就是平时咱们查东西时候常用的两种手段 无非就是为了提高我们找东西的效率而已 那么我们平时又是怎么查东西呢 聚集索引 聚集索引 来源于生活尝试 这中索引可以说是按照数据的物理存储进行划分的
  • 工作中遇到的数据库死锁问题 - 排查方案 CannotAcquireLockException

    问题 重现 正常情况下 销售人员在使用我们的销售系统为客户创建订单时候 后台java代码就会开启事务 然后往数据库中添加订单信息和订单详情信息 以及一些其他业务操作 但由于某次异常操作 可能是网络或者其他的原因 导出系统出现问题无法工作 于
  • Font Awesome矢量版,十六进制版,WPF字体使用

    Font Awesome为您提供可缩放的矢量图标 您可以使用CSS所提供的所有特性对它们进行更改 包括 大小 颜色 阴影或者其它任何支持的效果 WPF可以使用FontAwesome字体 Android可以使用FontAwesome字体 需要
  • python小游戏毕设 接金币小游戏设计与实现 (源码)

    文章目录 1 项目简介 1 游戏介绍 2 实现效果 3 开发工具 3 1 环境配置 3 2 Pygame介绍 4 具体实现 5 最后 1 项目简介 Hi 各位同学好呀 这里是L学长 今天向大家分享一个今年 2022 最新完成的毕业设计项目作
  • 【华为OD机试真题】日志采集系统(python)100%通过率 超详细代码注释 代码优化

    华为OD机试真题 2022 2023 真题目录 点这里 华为OD机试真题 信号发射和接收 试读 点这里 华为OD机试真题 租车骑绿道 试读 点这里 日志采集系统 时间限制 1s空间限制 256MB限定语言 不限 题目描述 日志采集是运维系统
  • 【Android】BottomNavigationView+ViewPager实现底部导航栏(步骤+源码)

    吐糟大会 时隔好久再一次在博客上与大家见面 上一年九月份怀疑自己不适合这行毅然辞职 我没结婚没车贷没房贷本以为能很潇洒 但现实给我开了个玩笑 我发现除了这一行其他什么都不会 也许是我很懒吧 为了能吃饱饭我再次踏入这一行 回归初衷为了让更多刚