Android ViewPager2 + Fragment + BottomNavigationView 联动

news2024/10/2 0:11:26

Android ViewPager2 + Fragment + BottomNavigationView 联动

本篇主要介绍一下 ViewPager2 + Fragment + BottomNavigationView , 上篇中把ViewPager2和Fragment 联动起来了, 本篇主要把 BottomNavigationView集成进去

2022-11-25 17.31.02

概述

BottomNavigationView 是一个底部导航控件, 现在要实现的效果就是 滑动ViewPager2 中的Fragment 并且底部BottomNavigationView 菜单部分跟着联动 同理反过来 点击BottomNavigationView 的时候 ViewPager2中的Fragment 也对应滑动, 下面来看看如何实现的吧

实现思路

1.Activity 布局文件中引入 ViewPager2 控件
2.编写menu文件 提供给BottomNavigationView 用于展示
3.Activity 布局文件中引入BottomNavigationView 控件
4.编写 Fragment 用于填充到ViewPager2中
5.编写Adapter 实现 FragmentStateAdapter
6.BottomNavigationView添加 setOnItemSelectedListener 联动ViewPager2
7.ViewPager2 添加 registerOnPageChangeCallback 联动 BottomNavigationView

代码实现

下面就来按照上面的思路一步步实现代码啦!

1.Activity 布局文件中引入 ViewPager2 控件

<?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=".ViewPager2BottomActivity">


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2bottom"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/bootomnav2"
        />


</androidx.constraintlayout.widget.ConstraintLayout>

2.编写menu文件 提供给BottomNavigationView 用于展示

图标icon 自己配置吧

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

    <item
        android:title="首页"
        android:id="@+id/home_item"
        android:icon="@drawable/ic_baseline_home_24"
        />

    <item
        android:title="类型"
        android:id="@+id/type_item"
        android:icon="@drawable/ic_baseline_merge_type_24"
        />

    <item
        android:title="添加"
        android:id="@+id/add_item"
        android:icon="@drawable/ic_baseline_add_24"
        />

    <item
        android:title="设置"
        android:id="@+id/setting_item"
        android:icon="@drawable/ic_baseline_settings_24"
        />
</menu>

3.Activity 布局文件中引入BottomNavigationView 控件

package com.johnny.slzzing;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.w3c.dom.Text;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link Bottom2Fragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class Bottom2Fragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public Bottom2Fragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment Bottom2Fragment.
     */
    // TODO: Rename and change types and number of parameters
    public static Bottom2Fragment newInstance(String param1, String param2) {
        Bottom2Fragment fragment = new Bottom2Fragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_bottom2, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        TextView textView = view.findViewById(R.id.textview2);
        //把动态传入的参数设置到 textView上
        textView.setText(mParam1);
    }
}

fragment_bottom2.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=".ViewPager2BottomActivity">


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2bottom"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/bootomnav2"
        />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bootomnav2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/viewpager2bottom"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_item_menu"                                        
        app:labelVisibilityMode="labeled" 
        />
<!-- 这个要设置 app:labelVisibilityMode="labeled"  才能显示图标文字 因为我这里超过了3个-->        
</androidx.constraintlayout.widget.ConstraintLayout>

4.编写 Fragment 用于填充到ViewPager2中

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Bottom2Fragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/textview2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:gravity="center"
        android:textSize="25sp"
        android:textStyle="bold"
        android:textColor="@color/black"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

5.编写Adapter 实现 FragmentStateAdapter

上篇已经说过了 直接继承 FragmentStateAdapter

class MyViewPager2BottomAdapter extends FragmentStateAdapter {

    List<Fragment> fragmentList;
    public MyViewPager2BottomAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> list) {
        super(fragmentActivity);
        this.fragmentList = list;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getItemCount() {
        return fragmentList.size();
    }
}

6.BottomNavigationView添加 setOnItemSelectedListener 联动ViewPager2

bottomNavigationView.setOnItemSelectedListener核心方法

Acitivity 中实现如下代码:

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_pager2_bottom);

        viewPager2 = findViewById(R.id.viewpager2bottom);
        bottomNavigationView = findViewById(R.id.bootomnav2);
        MyViewPager2BottomAdapter myViewPager2BottomAdapter =
                new MyViewPager2BottomAdapter(this,initFragmentList());
        viewPager2.setAdapter(myViewPager2BottomAdapter);
        //重点 设置 bottomNavigationView 的item 的点击事件 设置viewPager2的联动
        bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                int itemId = item.getItemId();
                switch (itemId){
                    case R.id.home_item:
                        viewPager2.setCurrentItem(0);
                        break;
                    case R.id.type_item:
                        viewPager2.setCurrentItem(1);
                        break;
                    case R.id.add_item:
                        viewPager2.setCurrentItem(2);
                        break;
                    case R.id.setting_item:
                        viewPager2.setCurrentItem(3);
                        break;
                }
                return true;
            }
        });

    }

7.ViewPager2 添加 registerOnPageChangeCallback 联动 BottomNavigationView

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_pager2_bottom);

    viewPager2 = findViewById(R.id.viewpager2bottom);
    bottomNavigationView = findViewById(R.id.bootomnav2);
    MyViewPager2BottomAdapter myViewPager2BottomAdapter =
            new MyViewPager2BottomAdapter(this,initFragmentList());
    viewPager2.setAdapter(myViewPager2BottomAdapter);

    bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            int itemId = item.getItemId();
            switch (itemId){
                case R.id.home_item:
                    viewPager2.setCurrentItem(0);
                    break;
                case R.id.type_item:
                    viewPager2.setCurrentItem(1);
                    break;
                case R.id.add_item:
                    viewPager2.setCurrentItem(2);
                    break;
                case R.id.setting_item:
                    viewPager2.setCurrentItem(3);
                    break;
            }
            return true;
        }
    });
     //重点 实现滑动的时候 联动 bottomNavigationView的selectedItem
    viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            switch (position){
                case 0:
                    bottomNavigationView.setSelectedItemId(R.id.home_item);
                    break;
                case 1:
                    bottomNavigationView.setSelectedItemId(R.id.type_item);
                    break;
                case 2:
                    bottomNavigationView.setSelectedItemId(R.id.add_item);
                    break;
                case 3:
                    bottomNavigationView.setSelectedItemId(R.id.setting_item);
                    break;
            }
        }
    });

}

image-20221125172800393

总结

本篇主要介绍了 如何把ViewPager2 + Fragment + BottomNavigationView 集成起来并且实现ViewPager2和BottomNavigationView的双向联动

ViewPager和ViewPager2 一些区别:

  • ViewPager 的 Adapter 继承 FragmentStatePagerAdapter 而 ViewPager2 的Adapter 继承 FragmentStateAdapter
  • ViewPager 滑动监听是 viewPager.addOnPageChangeListener方法 而ViewPager2 滑动监听是 registerOnPageChangeCallback 方法

欢迎大家访问 个人博客 Johnny小屋
欢迎关注个人公众号

欢迎关注个人公众号

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

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

相关文章

import一个“太极”库,让Python代码提速100倍

众所周知&#xff0c;Python的简单和易读性是靠牺牲性能为代价的—— 尤其是在计算密集的情况下&#xff0c;比如多重for循环。 不过现在&#xff0c;大佬胡渊鸣说了&#xff1a; 只需import 一个叫做“Taichi”的库&#xff0c;就可以把代码速度提升100倍&#xff01; 不信&…

Springboot配置文件加密

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、jasypt二、使用步骤1.引入依赖2.添加配置3.生成密钥3.idea启动添加环境变量3.linux环境启动报错前言 前面叙述了数据传递过程中的加密&#xff0c;需要使用…

docker 命令 相关

mysql 主从复制&#xff1a; 一主多从配置 主服务器&#xff1a;容器名mysql-master&#xff0c;端口3307 从服务器&#xff1a;容器名mysql-slave1&#xff0c;端口3308 从服务器&#xff1a;容器名mysql-slave2&#xff0c;端口3309 注意&#xff1a;如果此时防火墙是开启…

[附源码]计算机毕业设计JAVA星期八酒店管理系统

[附源码]计算机毕业设计JAVA星期八酒店管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM myba…

ASEMI整流桥堆GBJ406的作用,GBJ406整流桥型号及参数

编辑-Z GBJ406整流桥型号及参数&#xff0c;ASEMI整流扁桥GBJ406电性参数为4A反向电压600V&#xff1b;浪涌电流Ifsm为120A&#xff1b;工作温度为&#xff1a;-55℃~150℃&#xff1b;采用台湾进GPP芯片中有4个芯片&#xff0c;芯片尺寸84MIL。 GBJ406参数描述 型号&#xf…

FCPX插件Yanobox Motype for mac(43种动画发生器)

Yanobox Motype mac版是要您后期制作的福音。插件仅适用于&#xff1a;Mac OSX 苹果系统下&#xff1a;Final Cut Pro X 、Motion&#xff0c;Premiere Pro和After Effects剪辑软件。随意更改字体大小和位置&#xff0c;随意制作你喜欢的视频&#xff01; 提供了一个多功能的…

从根上理解Cglib与JDK动态代理

最近在阅读到了Spring源码对于两种动态代理使用在不同场景下的使用&#xff0c;两种方式各有利弊写一篇文加深自己的认识。文中对于源码的涉及较少&#xff0c;更多的是作者自己的理解和举例&#xff0c;然后通过部分源码验证。 首先看两个面试经常会遇到的关于Spring的问题&a…

数理统计笔记7:分类数据分析-拟合优度检验和列联分析

引言 数理统计笔记的第7篇介绍了分类数据分析的方法&#xff0c;包括拟合优度检验和列联分析&#xff0c;给出了两者的卡方检验量的表达式&#xff0c;并且用例子进行了说明&#xff0c;最后谈了列联分析需要注意的问题。 引言什么是分类型数据拟合优度检验χ2\chi^2χ2统计量例…

使用AWS-AppSync实时监控物联网设备iOS端

aws-appsync-iot-core-实时iOS端示例 第一步参考如下资料 第一步找资料 网址&#xff1a; https://aws.amazon.com/cn/blogs/mobile/iot-with-aws-appsync/ iOS的sdk是 &#xff1a; https://github.com/aws-amplify/aws-sdk-ios android的sdk是&#xff1a; https://gith…

[附源码]JAVA毕业设计基于web的公益募捐网站(系统+LW)

[附源码]JAVA毕业设计基于web的公益募捐网站&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目…

Apache JMeter压测工具

1.工具介绍 是什么 JMeter是一个软件&#xff0c;使负载测试或业绩为导向的业务&#xff08;功能&#xff09;测试不同的协议或技术。 Apache软件基金会的Stefano Mazzocchi JMeter的最初的开发。他写道&#xff1a;它主要对 Apache JServ&#xff08;现在称为如Apache Tomcat…

项目管理工具dhtmlxGantt入门教程(一):如何安装dhtmlxGantt

您可以使用 NuGet 、 Bower 或 npm 包管理器将 dhtmlxGantt 包安装到您的项目中,也可以从 CDN 中包含必要的 JS/CSS 文件。 DhtmlxGantt正版试用下载&#xff08;qun&#xff1a;764148812&#xff09;https://www.evget.com/product/4213/download NuGet 安装 dhtmlxGantt …

C++使用gRPC实例

什么是gRPC RPC 即远程过程调用协议&#xff08;Remote Procedure Call Protocol&#xff09;&#xff0c;可以让我们像调用本地对象一样发起 远程调用。RPC 凭借其强大的治理功能&#xff0c;成为解决分布式系统通信问题的一大利器。 gRPC是一个现代的、高性能、开源的和语言…

Python数据分析实战-实现一维列表(数组)和多维列表(数组)的相互转化(附源码和实现效果)

前面我介绍了可视化的一些方法以及机器学习在预测方面的应用&#xff0c;分为分类问题&#xff08;预测值是离散型&#xff09;和回归问题&#xff08;预测值是连续型&#xff09;&#xff08;具体见之前的文章&#xff09;。 从本期开始&#xff0c;我将做一个数据分析类实战…

[附源码]计算机毕业设计springboot校园疫情管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

文件的上传与下载

文章目录一、 实验目的&#xff1a;二、实验要求&#xff1a;三、实验内容&#xff1a;1、单文件上传2、多文件上传3、上传文件的大小限定4、实现文件的下载功能&#xff0c;并解决下载乱码问题一、 实验目的&#xff1a; 掌握Servlet的HttpServletRequest对文件上传的支持&am…

内存管理---分页机制

目录 物理内存管理带来的问题 直接映射 一级页表 二级页表 参考&#xff1a; &#xff08;C语言内存七&#xff09;分页机制究竟是如何实现的&#xff1f; - Smah - 博客园 物理内存管理带来的问题 比如4GB的flash, 如果应用程序可直接访问物理内存&#xff0c;那么可能一个…

云小课|基于华为云WAF的日志运维分析,构筑设备安全的城墙

阅识风云是华为云信息大咖&#xff0c;擅长将复杂信息多元化呈现&#xff0c;其出品的一张图(云图说)、深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云。更多精彩内容请单击此处。 摘要&#xff1a;云日志服务用于收集来自主机和云服务的日志数据&#x…

windows安装docker版青龙面板

1.下载docker Docker Desktop 官方下载地址&#xff1a; windows docker 2 管理员运行PowerShell&#xff0c;执行下面的命令(Hyper-V 和容器特性) Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All3.运行第一步下载好的exe 双击下载的 Docker fo…

springboot基于vue.js的掌上博客系统的设计与实现毕业设计源码063131

Springboot掌上博客系统的设计与实现 摘 要 掌上博客系统是当今网络的热点&#xff0c;博客技术的出现使得每个人可以零成本、零维护地创建自己的网络媒体&#xff0c;Blog站点所形成的网状结构促成了不同于以往社区的Blog文化&#xff0c;Blog技术缔造了“博客”文化。 本文课…