Android ViewPager2 + Fragment + BottomNavigationView 联动

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

概述

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;
}
}
}); }

总结

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

ViewPager和ViewPager2 一些区别:

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

欢迎大家访问 个人博客 Johnny小屋

欢迎关注个人公众号

Android ViewPager2 + Fragment + BottomNavigationView 联动的更多相关文章

  1. Android 底部按钮BottomNavigationView + Fragment 的使用(二)

    这里来试验BottomNavigationView + Fragment 底部按钮通过点击底部选项,实现中间的Fragment进行页面的切换. 使用BottomNavigationView 控件,实现 ...

  2. Android 底部按钮BottomNavigationView + Fragment + viewPager 的使用(一)

    实现的效果,左右滑动,底部栏跟着滑动,中间加的是分帧的页面        上代码:主页面activity_main.xml <?xml version="1.0" encod ...

  3. Android:Activity+Fragment及它们之间的数据交换.

    Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...

  4. Android中Fragment和ViewPager那点事儿(仿微信APP)

    在之前的博文<Android中使用ViewPager实现屏幕页面切换和引导页效果实现>和<Android中Fragment的两种创建方式>以及<Android中Fragm ...

  5. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

  6. Android中Fragment的两种创建方式

    fragment是Activity中用户界面的一个行为或者是一部分.你可以在一个单独的Activity上把多个Fragment组合成为一个多区域的UI,并且可以在多个Activity中再使用.你可以认 ...

  7. android之Fragment基础详解(一)

      一.Fragment的设计哲学 Android在3.0中引入了fragments的概念,主要目的是用在大屏幕设备上--例如平板电脑上,支持更加动态和灵活的UI设计.平板电脑的屏幕比手机的大得多,有 ...

  8. Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3364728.html 我前两天写过一篇博客<Android使用Fragment来 ...

  9. android之fragment的使用

    android中的fragment与html中的div很类似,下图中通过左边的按键可以控制右边的显示内容.右边的内容就是一个fragment,通过点击按键来控制fragment的实现. 工程目录 需要 ...

  10. Android使用Fragment定义弹出数字键盘

    fragment主布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmln ...

随机推荐

  1. MySQL 数据更新过程

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247486441&idx=1&sn=fcf93709 ...

  2. 几篇关于MySQL数据同步到Elasticsearch的文章---第五篇:logstash-input-jdbc实现mysql 与elasticsearch实时同步深入详解

    文章转载自: https://blog.csdn.net/laoyang360/article/details/51747266 引言: elasticsearch 的出现使得我们的存储.检索数据更快 ...

  3. SpringBoot项目的CI配置 # 安全变量

    运行GitLab Runner容器 参考Run GitLab Runner in a container - Docker image installation and configuration 执 ...

  4. SQL通用语法和SQL分类

    SQL通用语法 1.SQL 语句可以单行或多行书写,以分号结尾 2.可使用空格和缩进来增强语句的可读性 3.MySQL 数据库的SQL语句不区分大小写,关键字建议使用大写 4.3种注释 单行注释: - ...

  5. 如何使用netlify部署vue应用程序

    什么是Netlify? Netlify是一个现代网站自动化系统,其JAM架构代表了现代网站的发展趋势.所谓JAM,就是指基于客户端JavaScript.可重用API和预构建Markup标记语言的三者结 ...

  6. TypeScript(一)基本使用

    一:导入TypeScript npm i typescript 或者 npm i typescript -g(全局导入) 二:编译Ts文件为Js(道理跟Sass转Css一样) 在当前文件目录终端中输入 ...

  7. ARC148游记

    A - mod M 题目链接 这道题我们可以首先对于所有的数 $%2$ ,可以证明出答案最多不超过 $2$ ,此时我们就可以把问题转化为:是否存在一个数使得序列 $a$ 中所有元素减去这个数之后的最大 ...

  8. 【编程学习】MATLAB

    目录 一.MATLAB基础 1. 学会完成MATLAB的安装与启动 1.1 软件包下载 1.2 安装步骤 2. 矩阵的基本操作与运算 2.1 矩阵的简单输入与操作 2.2 矩阵的基本运算 2.2.1 ...

  9. 魔改editormd组件,优化ToC渲染效果

    前言 我的StarBlog博客目前使用 editor.md 组件在前端渲染markdown文章,但这个组件自动生成的ToC(内容目录)不是很美观,我之前魔改过一个树形组件 BootStrap-Tree ...

  10. jsp和java的结合使用显示学生信息

    package com.zyz; public class Student { private String ID; // 学号 private String name; // 姓名 private ...