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. 数论进阶&#160;

    数论进阶 扩展欧几里得算法 裴蜀定理(Bézout's identity) \(1\) :对于任意整数 \(a\),\(b\) ,存在一对整数 \(x\) ,\(y\) ,满足 \(ax+by=GCD ...

  2. 我的Vue之旅、04 CSS媒体查询完全指南(Media Quires)

    什么是SCSS Sass: Sass Basics (sass-lang.com) SCSS 是 CSS 的预处理器,它比常规 CSS 更强大. 可以嵌套选择器,更好维护.管理代码. 可以将各种值存储 ...

  3. parted创建磁盘分区并创建LVM(Linux合并多块大于2T的磁盘并合并到一个分区)

    文章转载自:https://blog.csdn.net/likemebee/article/details/85630808

  4. rabbitmq的内存节点和磁盘节点

    RabbitMQ集群里有内存节点与磁盘节点之分. 所谓内存节点,就是将元数据(metadata)都放在内存里,磁盘节点就是放在磁盘上.(内存节点将全部的队列,交换器,绑定关系,用户,权限,和vhost ...

  5. 使用metricbeat监控system和nginx

    下载并解压缩metricbeat metricbeat.yml配置文件设置: setup.kibana: host: "192.168.75.21:5601" output.ela ...

  6. Beats: Filebeat和pipleline processors

    简要来说: 使用filebeat读取log日志,在filebeat.yml中先一步处理日志中的个别数据,比如丢弃某些数据项,增加某些数据项. 按照之前的文档,是在filebeat.yml中操作的,具体 ...

  7. Security:如何安装 Elastic SIEM 和 EDR

    转载自:https://elasticstack.blog.csdn.net/article/details/114023944 需要学习的地方:生成SSL证书 图片结合最下方的代码文字使用 last ...

  8. 实战---在Portainer中编排docker-compose.yml文件

    选择要部署容器的主机上,不用事先安装配置docker-compose 官方示例文档地址,2.0版本的:https://docs.docker.com/compose/compose-file/comp ...

  9. 安全强化Linux 服务器的七个步骤

    这篇入门文章将向你介绍基本的 Linux 服务器安全知识.虽然主要针对 Debian/Ubuntu,但是你可以将此处介绍的所有内容应用于其他 Linux 发行版.我也鼓励你研究这份材料,并在适用的情况 ...

  10. 跟我学Python图像处理丨傅里叶变换之高通滤波和低通滤波

    摘要:本文讲解基于傅里叶变换的高通滤波和低通滤波. 本文分享自华为云社区<[Python图像处理] 二十三.傅里叶变换之高通滤波和低通滤波>,作者:eastmount . 一.高通滤波 傅 ...