RecyclerView与ViewPager2
1:RecyclerView
ListView具有以下几种不足
1.没办法实现左右滑动,拓展性差
2.运行效率比较低,需要手动优化性能
RecyclerView可以有效的解决这些问题,这也是为什么RecyclerView逐渐取代了ListView
1.1:基本使用方法
以前的Android Studio要想使用RecyclerView必须得在build.gradle (Moudule) 的 dependencies中加入
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.recyclerview:recyclerview-selection:1.1.0")
而我用的Android Studio 2021.3.1不用加入以上代码,就可以直接用
1.1.1定制 RecyclerView 界面
修改activity_main.xml 中的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycle_view_0"/>
</LinearLayout>
在res中的layout下面建一个item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
这个xml文件时用来展示RecyclerView 中的每个数据项,
我们来看一看它的design

构建一个类,这个类是用来说明对象的属性
比如我的RecyclerView里面要展示的是对象的姓名
package com.example.recycleview_0;
public class idol {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String name;
}
1.1.2创建适配器
为什么要创建一个适配器呢,因为数据是无法直接传递给RecyclerView的(和ListView一样),我们需要适配器
适配器的初始化:
package com.example.recycleview_0;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class Adapter_0 extends RecyclerView.Adapter<Adapter_0.Adapter_0Holder> {
@NonNull
@Override
public Adapter_0.Adapter_0Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull Adapter_0.Adapter_0Holder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
public class Adapter_0Holder extends RecyclerView.ViewHolder {
public Adapter_0Holder(@NonNull View itemView) {
super(itemView);
}
}
}
首先我们先定义了一个内部类Adapter_0Holder
Adapter_0Holder要继承RecyclerView.ViewHolder然后Adapter_0Holder的构造函数里面要传入一个View参数,这个参数通常就是RecyclerView子项的最外层布局,我们可以通过findViewById()获取布局中的TextView实例
public class Adapter_0Holder extends RecyclerView.ViewHolder {
TextView mTextView;
public Adapter_0Holder(@NonNull View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.text_view);
}
}
这时候我们再来完善Adapter_0里面的内容
我们先在Adapter_0里面添加一个构造方法,便于将要展示的值传进来
private List<idol>mIdols;
public Adapter_0(List<idol> idols) {
mIdols = idols;
}
然后再重写里面的onCreateViewHolder(),onBindViewHolder(),**getItemCount()**方法
@NonNull
@Override
public Adapter_0Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new Adapter_0Holder(view);
}
onCreateViewHolder()方法是用于创建Adapter_0Holder实例,我们在这个方法中将item布局加载进来,创建一个Adapter_0Holder实例,并把加载出来的布局传入到构造函数中,最后将Adapter_0Holder的实例返回
@Override
public void onBindViewHolder(@NonNull Adapter_0Holder holder, int position) {
idol idol = mIdols.get(position);
holder.mTextView.setText(idol.getName());
}
onBindViewHolder()是用于对RecyclerView子项的数据进行赋值操作,每个子项被滚动到屏幕内时会执行,通过position得到当前项的idol实例,然后将数据设置到Adapter_0Holder中的TextView中
@Override
public int getItemCount() {
return mIdols.size();
}
getItemCount()用来告诉RecycleView一共有多少子项,直接返回数据源的长度就行了
方法 | 作用 |
---|
Adapter_0的构造方法 | 便于将要展示的值传进来 | onCreateViewHolder() | 创建一个Adapter_0Holder实例(创建内部类的实例),把加载的布局传入内部类Adapter_0Holder的构造方法中,最后返回Adapter_0Holder这个实例 | 内部类Adapter_0Holder | 有用的主要是它的构造方法,用findViewById将item中的TextView实例化 | onBindViewHolder() | onBindViewHolder()里面有一个参数是postion,我们就根据这个postion给相应的子项赋值 | getItemCount() | 返回RecycleView中的子项的长度 |
1.1.3MainActivity里面的修改
public class MainActivity extends AppCompatActivity {
List<idol>mIdols = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
RecyclerView recyclerView = findViewById(R.id.recycle_view_0);
LinearLayoutManager linearLayout = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayout);
Adapter_0 adapter_0 = new Adapter_0(mIdols);
recyclerView.setAdapter(adapter_0);
}
private void init(){
for(int i=0;i<100;i++){
idol idol = new idol();
idol.name="向晚";
mIdols.add(idol);
}
}
}
| 作用 |
---|
init() | 初始化所有的数据 | RecyclerView recyclerView = findViewById(R.id.recycle_view_0) | 将RecyclerView实例化 | LinearLayoutManager linearLayout = new LinearLayoutManager(this) | 指定RecyclerView的布局 | recyclerView.setLayoutManager(linearLayout) | 完成RecyclerView布局的适配设置 | Adapter_0 adapter_0 = new Adapter_0(mIdols) | 创建Adapter_0实例 | recyclerView.setAdapter(adapter_0) | 完成适配器的设置,RecyclerView和数据之间的关联就建立了 |
效果如下

可以向下滑动
1.2横向滑动
横向滑动就比纵向滑动多了几行代码,很简单
1.2.1定制RecyclerView界面
在res中的layout里的item.xml中加一行代码
android:orientation="vertical";
1.2.2MainActivity里面的修改
在LinearLayoutManager下面加一句
linearLayout.setOrientation(LinearLayoutManager.HORIZONTAL);
下面是效果

可以左右滑动
1.3RecyclerView的一些理解
我们在onCreateViewHolder和onBindViewHolder中分别加上
Log.d(“TAG”,“onCreateViewHolder”);
Log.d(“TAG”,“onBindViewHolder”);
当刚开启虚拟机的时候:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M1iUi9dq-1666860990601)(C:\Users\ok\AppData\Roaming\Typora\typora-user-images\image-20221026165808116.png)]](https://img-blog.csdnimg.cn/11b1460a5ded47abbe7b256e92f8bd34.png)
有14个向晚
这时候你再看Logcat
你会发现Logcat里面分别有14个onCreateViewHolder和14个onBindViewHolder
(而且,Logcat里面是出现一个onCreateViewHolder就出现一个onBindViewHolder)
这个RecyclerView是可以左右滑动的,这时候,我们将RecyclerView右滑
看Logcat
设置一个i=0;
设置一个n=0;
每次执行一次onBindViewHolder,让i++
每次执行一次onCreateViewHolder让n++
你会发现当n=19后,就再也不增加了即onCreateViewHolder不再执行
而i会一直增加,即onBindViewHolder会一直执行
我原本以为是向晚输的太少,当我输200个向晚后,发现依然n=19就不增加了
当我把字体的大小改变时,发现n的大小发生了改变
且是textSize越大,n的最大值越小
1.4RecyclerView的一些改进
在开发过程中有一个约定俗成的一点就是,尽量不要让过多的item暴露出来
,因为item过多的话容易导致内存泄漏
1.4.1内存泄漏
内存泄露是指:内存泄漏也称作"存储渗漏",用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。
解决的方法就是在**onBindViewHolder()方法中将holder.mTextView.setText(idol.getName())中的mTextView.setText(idol.getName())**封装,
在内部类的构造方法中
public void bind(String text){
mTextView.setText(text);
}
然后
@Override
public void onBindViewHolder(@NonNull Adapter_0.Adapter_0Holder holder, int position) {
idol idol = mIdols.get(position);
holder.bind(idol.getName());
++i;
Log.d("TAG","onBindViewHolder"+i);
}
其实内存泄漏也不能这么说,这样优化的目的就是为了:让本来就应该干这个的方法干这件事
1.5RecyclerView和ListView的区别
RecyclerView | ListView |
---|
可以实现左右滑动 | 不能实现左右滑动 | onCreateViewHolder执行的次数一定小于等于item的个数 | onCreateViewHolder等于item的个数 | 有回收机制 | 没有回收机制 |
2:ViewPager2
ViewPager1据说比较恶心,那就不看了,ViewPager2的操作和RecyclerView的操作差不多
RecyclerView的直观感受就是可以左右滑动或者上下滑动
而ViewPager2的直观感受就是实现水平翻页的效果
2.1:基本使用方法
2.1.1定制ViewPager2界面
修改activity_main.xml 中的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/viewpager2"/>
</LinearLayout>
在res中的drawable下放一张abc.jpg

然后在res中的layout下面新建一个item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:id="@+id/textview_0"/>
<ImageView
android:layout_below="@+id/textview_0"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/image_0"/>
</RelativeLayout>
看看它的design

然后在原来MainActivity所在的包下新建一个类
还是把它命名为idol
为了能明显看出切换的效果,我们在里面不仅定义了name,还定义了picture
package com.example.viewpage2_0;
public class idol {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPicture() {
return picture;
}
public void setPicture(int picture) {
this.picture = picture;
}
public int picture;
}
2.1.2创建适配器
package com.example.viewpage2_0;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class recyclerView_0 extends RecyclerView.Adapter<recyclerView_0.recyclerView_0Holder> {
public recyclerView_0(List<idol> idols) {
mIdols = idols;
}
private List<idol>mIdols;
@NonNull
@Override
public recyclerView_0.recyclerView_0Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new recyclerView_0Holder(view);
}
@Override
public void onBindViewHolder(@NonNull recyclerView_0.recyclerView_0Holder holder, int position) {
idol idol = mIdols.get(position);
holder.mImageView.setImageResource(idol.getPicture());
holder.mTextView.setText(idol.getName());
}
@Override
public int getItemCount() {
return mIdols.size();
}
public class recyclerView_0Holder extends RecyclerView.ViewHolder {
TextView mTextView;
ImageView mImageView;
public recyclerView_0Holder(@NonNull View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textview_0);
mImageView = itemView.findViewById(R.id.image_0);
}
}
}
这块和RecyclerView基本一模一样
所以没啥必要再写
2.1.3MainActivity里面修改
public class MainActivity extends AppCompatActivity {
private List<idol>mIdols = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
ViewPager2 viewPager2 = findViewById(R.id.viewpager2);
recyclerView_0 horizontalVpAdapter = new recyclerView_0(mIdols);
viewPager2.setAdapter(horizontalVpAdapter);
}
private void init(){
for(int i = 0;i<3;i++){
idol idol = new idol();
idol.name = "关注向晚大魔王";
idol.picture=R.drawable.abc;
mIdols.add(idol);
}
}
}
你会发现这块和RecyclerView也差不多
为数不多的不同点就是ViewPager2里面不用指定布局还有布局的适配
来,我们来看看效果

我不知道咋弄动图,反正就是可以向下滑
2.2:横向滑动
这块也和RecyclerView差不多
在layout.item里面加入:
android:orientation="vertical"
在活动中加一句
viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
更简单了
3:RecyclerView和ViewPager2的异同点
相同点 | 都要创建适配器 | 都可以左右滑动,上下滑动 | 都有回收机制 |
---|
不同点 | RecyclerView需要实例化布局,而ViewPager2不需要 | 正因为RecyclerView布局需要实例化,ViewPager2不需要,所以RecyclerView的实现左右滑动要稍微比ViewPager2麻烦 | |
4.ViewPager2与Fragment联动效果
其实在写ViewPager2的时候我就在想,当用ViewPager2时,能不能实现无限滑动的效果
我想的是在MainActivity的init()方法里面,在for循环中加一句(因为我的i是从0开始,等于3的时候结束),i=3时,i又等于了0,感觉没问题,觉得可以实现这个功能,但是直接应用闪退。
突然想了一下,应该是因为ViewPager2的回收机制
,然后突然发现,ViewPager2与Fragment联动好像可以解决这个问题
Fragment是Activity的一部分,或者页面的一部分,当页面上的内容太多需要针对性加载时可以采用Fragment;ViewPager2是管理多个Fragment的工具.
4.1:水平翻页

先在MainActivity所在的包下建立一个Fragment(Blank)
并且修改**Fragment(Blank)**里面的布局
4.11:修改Fragment(Blank)里面的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="@color/white"
tools:context=".BlankFragment"
android:orientation="vertical">
<TextView
android:id="@+id/mTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="36sp"
android:gravity="center"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="36sp"
android:id="@+id/anotherTextView"
android:gravity="center"/>
</LinearLayout>

这是它的design
4.12:修改Fragment里面的方法
package com.example.viewpage2_1;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class BlankFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public BlankFragment() {
}
public static BlankFragment newInstance(String param1, String param2) {
BlankFragment fragment = new BlankFragment();
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) {
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
这是刚才建立Fragment(Blank)时自动补充的代码
onCreate()上面的方法基本上用不着可以先不看
onCreate()里面的代码基本不用改
但是为了方便观察,我们在里面加上Log.d
public static BlankFragment newInstance(String param1, String param2) {
Log.d("BlankFragment","newInstance: 从主函数那边调过来创建碎片的实例");
BlankFragment fragment = new BlankFragment();
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) {
Log.d("BlankFragment","onCreate: 在这里创建碎片");
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) {
Log.d("BlankFragment","onCreateView: 在这里加载视图");
return inflater.inflate(R.layout.fragment_blank, container, false);
}
引入一个View方便后面的操作
View rootView;
public static BlankFragment newInstance(String param1, String param2) {
Log.d("BlankFragment","newInstance: 从主函数那边调过来创建碎片的实例");
BlankFragment fragment = new BlankFragment();
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) {
Log.d("BlankFragment","onCreate: 在这里创建碎片");
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) {
Log.d("BlankFragment","onCreateView: 在这里加载视图");
if(rootView == null) {
rootView = inflater.inflate(R.layout.fragment_blank, container, false);
}
initView();
return rootView;
}
private void initView() {
TextView textView = rootView.findViewById(R.id.mTextView);
TextView textView1 = rootView.findViewById(R.id.anotherTextView);
textView.setText(mParam1);
textView1.setText(mParam2);
}
4.13:创建构造器
再创建一个适配器
public class MyAdapter extends FragmentStateAdapter {
}
这时候它会提示你,让你重写2个方法,分别是
@NonNull
@Override
public Fragment createFragment(int position) {
return null;
}
@Override
public int getItemCount() {
return 0;
}
并且让你写出它的构造方法
public MyAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
public class MyAdapter extends FragmentStateAdapter {
private static final String TAG = "MyAdapter";
List<Fragment> fragments = new ArrayList<>();
public MyAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, List<Fragment> fragments) {
super(fragmentManager, lifecycle);
Log.d(TAG, "MyAdapter: 这是那个适配器的构造函数");
this.fragments = fragments;
Log.d(TAG, "MyAdapter: ");
}
@NonNull
@Override
public Fragment createFragment(int position) {
Log.d(TAG, "createFragment: 看看这是第几个视图" + position);
return fragments.get(position);
}
@Override
public int getItemCount() {
return fragments.size();
}
}
4.14:修改主布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/myViewPager"
android:background="@color/purple_500"
/>
</LinearLayout>
4.15:修改MainActivity
public class MainActivity extends AppCompatActivity {
ViewPager2 viewPager2;
private List<Fragment> fragments = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPage();
viewPager2 = findViewById(R.id.myViewPager);
MyAdapter myAdapter = new MyAdapter(getSupportFragmentManager(),
getLifecycle(),fragments);
viewPager2.setAdapter(myAdapter);
}
private void initPage() {
fragments.add(BlankFragment.newInstance("好好好","1"));
fragments.add(BlankFragment.newInstance("棒棒棒","2"));
fragments.add(BlankFragment.newInstance("good","3"));
fragments.add(BlankFragment.newInstance("better","4"));
}
}

向右滑动的效果
4.2:和TabLayout联动
首先先在MainActivity的layout里面加上
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tabLayout"/>
MainActivity里面加上
tabLayout = findViewById(R.id.tabLayout);
new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(tablayoutdata.get(position));
}
}).attach();
}
private void initPage() {
fragments.add(BlankFragment.newInstance("我最帅","1"));
fragments.add(BlankFragment.newInstance("我最丑","2"));
fragments.add(BlankFragment.newInstance("我很帅","3"));
fragments.add(BlankFragment.newInstance("我很丑","4"));
tablayoutdata.add("1");
tablayoutdata.add("2");
tablayoutdata.add("3");
tablayoutdata.add("4");
}
效果如图

可以通过按下面的键实现跳跃
4.3:ViewPager2+Fragment实现从最后一页滑到第一页
适配器里面的东西完全不用改变
在MainActivity里面加上
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
if(position==4){
viewPager2.setCurrentItem(0,false);
}
}
});
private void initPage() {
fragments.add(BlankFragment.newInstance("好好好","1"));
fragments.add(BlankFragment.newInstance("棒棒棒","2"));
fragments.add(BlankFragment.newInstance("good","3"));
fragments.add(BlankFragment.newInstance("better","4"));
fragments.add(BlankFragment.newInstance("好好","1"));
tablayoutdata.add("1");
tablayoutdata.add("2");
tablayoutdata.add("3");
tablayoutdata.add("4");
tablayoutdata.add("5");
}
至于为什么这么写呢,我只能说这是我为数不多会的了

和那种真正的轮流播放还是存在一定的差距的,你会发现和上面那张图比起来,TabLayout里面多了1个5
我的想法就是多弄了一个ViewPager2,最后一个ViewPager2和第一个Viewpager2设置的一摸一样,当它的TabLayout的值为4的时候,就已经进行到第5个ViewPager2了,这时候直接跳回到第一个ViewPager2就实现了这个
至于为什么要把最后一个和第一个设置成一样的,那是因为如果我把TabLayout去掉的话,就不容易看出来我写了5个ViewPager2而只会以为我写了4个
|