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. 从Java 9 到 Java 17 新特性梳理

    Java 9 新的创建集合的方法  // [1, 2, 3, 4]  List<Integer> integers = List.of(1, 2, 3, 4);  // {1,2,3}   ...

  2. Python数据分析教程(二):Pandas

    Pandas导入 Pandas是Python第三方库,提供高性能易用数据类型和分析工具 Pandas基于NumPy实现,常与NumPy和Matplotlib一同使用 两个数据类型:Series, Da ...

  3. ProxySQL(13):ProxySQL集群

    文章转载自:https://www.cnblogs.com/f-ck-need-u/p/9362822.html ProxySQL有原生的集群功能,但是这个原生的集群功能还正在试验阶段.本文会详细介绍 ...

  4. 6. EFK:免费的日志采集与可视化搜索套件

    收集日志是为了做进一步的分析.收集是第一步,收集到日志后还需要进行存储.索引,以便进行快速查询分析.我们还需要一个友好的查询界面,来方便用户使用日志. 本文介绍一个免费的开源软件组合,正好可以实现上述 ...

  5. 关于使用AWS上的RHEL-8.x/Redhat系统使用自己单独购买的Redhat官网license导致的yum命令报错处理

    我们在aws上使用市场提供的RHEL-8.x系统后,license相关的都是由aws官网一起提供了 最近笔者将aws上一台作过系统加固的RHEL-8.x导出到自己本地DC环境,也注册了Redhat官网 ...

  6. 微软出品自动化神器Playwright(Playwright+Java)系列(四) 之 浏览器操作

    写在前面 今天是国庆节的最后一天,明天又要上班了,真的是感觉好像才开始放假一样,还是因为失恋没缓过来吗? 我的国庆七天 第1天,当了近半天的司机,陪家人去各大超市去购物,下午在家躺····· 第2-5 ...

  7. 洛谷P7167 [eJOI 2020 Day1] Fountain (单调栈+ST)

    开两个数组:to[i][j]表示从i这个位置向下的第2j个圆盘是哪个,f[i][j]表示流满从i这个位置向下的 2j 个圆盘需要多少体积的水. 详情见代码: 1 #include<bits/st ...

  8. 利用Hutool-(Java工具类)实现验证码校验

    目录 Hutool工具类介绍 Hutool实现验证码生成 测试验证码生成 其他样式的验证码 第一篇是纯利用现有JDK提供的绘图类(ImageIO)类制作,这个过程比较复杂且需要了解ImageIO类. ...

  9. KubeEdge SIG AI发布首个分布式协同AI Benchmark调研

    摘要:AI Benchmark旨在衡量AI模型的性能和效能. 本文分享自华为云社区<KubeEdge SIG AI发布首个分布式协同AI Benchmark调研>,作者:KubeEdge ...

  10. 生成随机数的几种方法、Math.random()随机数的生成、Random()的使用

    第一种方法使用:System.currentTimeMillis(); final long l = System.currentTimeMillis(); final int rs = (int) ...