IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> RecyclerView与ViewPager2 -> 正文阅读

[移动开发]RecyclerView与ViewPager2

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);//这个R.id.text_view就是你res中的layout下面item.xml里的东西
    }
}

这时候我们再来完善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有用的主要是它的构造方法,用findViewByIditem中的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的一些理解

我们在onCreateViewHolderonBindViewHolder中分别加上

Log.d(“TAG”,“onCreateViewHolder”);

Log.d(“TAG”,“onBindViewHolder”);

当刚开启虚拟机的时候:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M1iUi9dq-1666860990601)(C:\Users\ok\AppData\Roaming\Typora\typora-user-images\image-20221026165808116.png)]

14向晚

这时候你再看Logcat

你会发现Logcat里面分别有14onCreateViewHolder和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的区别

RecyclerViewListView
可以实现左右滑动不能实现左右滑动
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

d9868ad6277f9e2f6bd2cad45a30e924b999f311

然后在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;
/**
 * A simple {@link Fragment} subclass.
 * Use the {@link BlankFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class BlankFragment 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 BlankFragment() {
        // 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 BlankFragment.
     */
    // TODO: Rename and change types and number of parameters
    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) {
        // Inflate the layout for this fragment
        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: 在这里加载视图");
        // Inflate the layout for this fragment
        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: 在这里加载视图");
        // Inflate the layout for this fragment
        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个

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:09:06  更:2022-10-31 12:09:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 23:49:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码