RecyclerView与ViewPager2
RecyclerView與ViewPager2
文章目錄
- RecyclerView與ViewPager2
- 1:RecyclerView
- 1.1:基本使用方法
- 1.1.1定制 RecyclerView 界面
- 1.1.2創(chuàng)建適配器
- 1.1.3MainActivity里面的修改
- 1.2橫向滑動(dòng)
- 1.2.1定制RecyclerView界面
- 1.2.2MainActivity里面的修改
- 1.3RecyclerView的一些理解
- 1.4RecyclerView的一些改進(jìn)
- 1.4.1內(nèi)存泄漏
- 1.5RecyclerView和ListView的區(qū)別
- 2:ViewPager2
- 2.1:基本使用方法
- 2.1.1定制ViewPager2界面
- 2.1.2創(chuàng)建適配器
- 2.1.3MainActivity里面修改
- 2.2:橫向滑動(dòng)
- 3:RecyclerView和ViewPager2的異同點(diǎn)
- 4.ViewPager2與Fragment聯(lián)動(dòng)效果
- 4.1:水平翻頁
- 4.11:修改Fragment(Blank)里面的布局
- 4.12:修改Fragment里面的方法
- 4.13:創(chuàng)建構(gòu)造器
- 4.14:修改主布局
- 4.15:修改MainActivity
- 4.2:和TabLayout聯(lián)動(dòng)
- 4.3:ViewPager2+Fragment實(shí)現(xiàn)從最后一頁滑到第一頁
1:RecyclerView
ListView具有以下幾種不足
1.沒辦法實(shí)現(xiàn)左右滑動(dòng),拓展性差
2.運(yùn)行效率比較低,需要手動(dòng)優(yōu)化性能
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.RecyclerViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/recycle_view_0"/> </LinearLayout>在res中的layout下面建一個(gè)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"><TextViewandroid:id="@+id/text_view"android:layout_width="match_parent"android:layout_height="wrap_content" /> </LinearLayout>這個(gè)xml文件時(shí)用來展示RecyclerView 中的每個(gè)數(shù)據(jù)項(xiàng),
我們來看一看它的design
構(gòu)建一個(gè)類,這個(gè)類是用來說明對(duì)象的屬性
比如我的RecyclerView里面要展示的是對(duì)象的姓名
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創(chuàng)建適配器
為什么要?jiǎng)?chuàng)建一個(gè)適配器呢,因?yàn)閿?shù)據(jù)是無法直接傳遞給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@Overridepublic Adapter_0.Adapter_0Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return null;}@Overridepublic void onBindViewHolder(@NonNull Adapter_0.Adapter_0Holder holder, int position) {}@Overridepublic int getItemCount() {return 0;}public class Adapter_0Holder extends RecyclerView.ViewHolder {public Adapter_0Holder(@NonNull View itemView) {super(itemView);}} }首先我們先定義了一個(gè)內(nèi)部類Adapter_0Holder
Adapter_0Holder要繼承RecyclerView.ViewHolder然后Adapter_0Holder的構(gòu)造函數(shù)里面要傳入一個(gè)View參數(shù),這個(gè)參數(shù)通常就是RecyclerView子項(xiàng)的最外層布局,我們可以通過findViewById()獲取布局中的TextView實(shí)例
public class Adapter_0Holder extends RecyclerView.ViewHolder {TextView mTextView;public Adapter_0Holder(@NonNull View itemView) {super(itemView);mTextView = itemView.findViewById(R.id.text_view);//這個(gè)R.id.text_view就是你res中的layout下面item.xml里的東西} }這時(shí)候我們?cè)賮硗晟?strong>Adapter_0里面的內(nèi)容
我們先在Adapter_0里面添加一個(gè)構(gòu)造方法,便于將要展示的值傳進(jìn)來
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()方法是用于創(chuàng)建Adapter_0Holder實(shí)例,我們?cè)谶@個(gè)方法中將item布局加載進(jìn)來,創(chuàng)建一個(gè)Adapter_0Holder實(shí)例,并把加載出來的布局傳入到構(gòu)造函數(shù)中,最后將Adapter_0Holder的實(shí)例返回
@Override public void onBindViewHolder(@NonNull Adapter_0Holder holder, int position) { idol idol = mIdols.get(position); holder.mTextView.setText(idol.getName()); }onBindViewHolder()是用于對(duì)RecyclerView子項(xiàng)的數(shù)據(jù)進(jìn)行賦值操作,每個(gè)子項(xiàng)被滾動(dòng)到屏幕內(nèi)時(shí)會(huì)執(zhí)行,通過position得到當(dāng)前項(xiàng)的idol實(shí)例,然后將數(shù)據(jù)設(shè)置到Adapter_0Holder中的TextView中
@Override public int getItemCount() {return mIdols.size(); }getItemCount()用來告訴RecycleView一共有多少子項(xiàng),直接返回?cái)?shù)據(jù)源的長度就行了
| Adapter_0的構(gòu)造方法 | 便于將要展示的值傳進(jìn)來 |
| onCreateViewHolder() | 創(chuàng)建一個(gè)Adapter_0Holder實(shí)例(創(chuàng)建內(nèi)部類的實(shí)例),把加載的布局傳入內(nèi)部類Adapter_0Holder的構(gòu)造方法中,最后返回Adapter_0Holder這個(gè)實(shí)例 |
| 內(nèi)部類Adapter_0Holder | 有用的主要是它的構(gòu)造方法,用findViewById將item中的TextView實(shí)例化 |
| onBindViewHolder() | onBindViewHolder()里面有一個(gè)參數(shù)是postion,我們就根據(jù)這個(gè)postion給相應(yīng)的子項(xiàng)賦值 |
| getItemCount() | 返回RecycleView中的子項(xiàng)的長度 |
1.1.3MainActivity里面的修改
public class MainActivity extends AppCompatActivity {List<idol>mIdols = new ArrayList<>();@Overrideprotected 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() | 初始化所有的數(shù)據(jù) |
| RecyclerView recyclerView = findViewById(R.id.recycle_view_0) | 將RecyclerView實(shí)例化 |
| LinearLayoutManager linearLayout = new LinearLayoutManager(this) | 指定RecyclerView的布局 |
| recyclerView.setLayoutManager(linearLayout) | 完成RecyclerView布局的適配設(shè)置 |
| Adapter_0 adapter_0 = new Adapter_0(mIdols) | 創(chuàng)建Adapter_0實(shí)例 |
| recyclerView.setAdapter(adapter_0) | 完成適配器的設(shè)置,RecyclerView和數(shù)據(jù)之間的關(guān)聯(lián)就建立了 |
效果如下
可以向下滑動(dòng)
1.2橫向滑動(dòng)
橫向滑動(dòng)就比縱向滑動(dòng)多了幾行代碼,很簡單
1.2.1定制RecyclerView界面
在res中的layout里的item.xml中加一行代碼
android:orientation="vertical";1.2.2MainActivity里面的修改
在LinearLayoutManager下面加一句
linearLayout.setOrientation(LinearLayoutManager.HORIZONTAL);下面是效果
可以左右滑動(dòng)
1.3RecyclerView的一些理解
我們?cè)?strong>onCreateViewHolder和onBindViewHolder中分別加上
Log.d(“TAG”,“onCreateViewHolder”);
Log.d(“TAG”,“onBindViewHolder”);
當(dāng)剛開啟虛擬機(jī)的時(shí)候:
有14個(gè)向晚
這時(shí)候你再看Logcat
你會(huì)發(fā)現(xiàn)Logcat里面分別有14個(gè)onCreateViewHolder和14個(gè)onBindViewHolder
(而且,Logcat里面是出現(xiàn)一個(gè)onCreateViewHolder就出現(xiàn)一個(gè)onBindViewHolder)
這個(gè)RecyclerView是可以左右滑動(dòng)的,這時(shí)候,我們將RecyclerView右滑
看Logcat
設(shè)置一個(gè)i=0;
設(shè)置一個(gè)n=0;
每次執(zhí)行一次onBindViewHolder,讓i++
每次執(zhí)行一次onCreateViewHolder讓n++
你會(huì)發(fā)現(xiàn)當(dāng)n=19后,就再也不增加了即onCreateViewHolder不再執(zhí)行
而i會(huì)一直增加,即onBindViewHolder會(huì)一直執(zhí)行
我原本以為是向晚輸?shù)奶?當(dāng)我輸200個(gè)向晚后,發(fā)現(xiàn)依然n=19就不增加了
當(dāng)我把字體的大小改變時(shí),發(fā)現(xiàn)n的大小發(fā)生了改變
且是textSize越大,n的最大值越小
1.4RecyclerView的一些改進(jìn)
在開發(fā)過程中有一個(gè)約定俗成的一點(diǎn)就是,盡量不要讓過多的item暴露出來
,因?yàn)?strong>item過多的話容易導(dǎo)致內(nèi)存泄漏
1.4.1內(nèi)存泄漏
內(nèi)存泄露是指:內(nèi)存泄漏也稱作"存儲(chǔ)滲漏",用動(dòng)態(tài)存儲(chǔ)分配函數(shù)動(dòng)態(tài)開辟的空間,在使用完畢后未釋放,結(jié)果導(dǎo)致一直占據(jù)該內(nèi)存單元。直到程序結(jié)束。(其實(shí)說白了就是該內(nèi)存空間使用完畢之后未回收)即所謂內(nèi)存泄漏。
解決的方法就是在**onBindViewHolder()方法中將holder.mTextView.setText(idol.getName())中的mTextView.setText(idol.getName())**封裝,
在內(nèi)部類的構(gòu)造方法中
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); }其實(shí)內(nèi)存泄漏也不能這么說,這樣優(yōu)化的目的就是為了:讓本來就應(yīng)該干這個(gè)的方法干這件事
1.5RecyclerView和ListView的區(qū)別
| 可以實(shí)現(xiàn)左右滑動(dòng) | 不能實(shí)現(xiàn)左右滑動(dòng) |
| onCreateViewHolder執(zhí)行的次數(shù)一定小于等于item的個(gè)數(shù) | onCreateViewHolder等于item的個(gè)數(shù) |
| 有回收機(jī)制 | 沒有回收機(jī)制 |
2:ViewPager2
ViewPager1據(jù)說比較惡心,那就不看了,ViewPager2的操作和RecyclerView的操作差不多
RecyclerView的直觀感受就是可以左右滑動(dòng)或者上下滑動(dòng)
而ViewPager2的直觀感受就是實(shí)現(xiàn)水平翻頁的效果
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"><TextViewandroid: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.ViewPager2android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:id="@+id/viewpager2"/> </LinearLayout>在res中的drawable下放一張abc.jpg
然后在res中的layout下面新建一個(gè)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"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="20dp"android:id="@+id/textview_0"/><ImageViewandroid:layout_below="@+id/textview_0"android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/image_0"/> </RelativeLayout>看看它的design
然后在原來MainActivity所在的包下新建一個(gè)類
還是把它命名為idol
為了能明顯看出切換的效果,我們?cè)诶锩娌粌H定義了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創(chuàng)建適配器
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@Overridepublic 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);}@Overridepublic 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());}@Overridepublic 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<>();@Overrideprotected 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 = "關(guān)注向晚大魔王";idol.picture=R.drawable.abc;mIdols.add(idol);}} }你會(huì)發(fā)現(xiàn)這塊和RecyclerView也差不多
為數(shù)不多的不同點(diǎn)就是ViewPager2里面不用指定布局還有布局的適配
來,我們來看看效果
我不知道咋弄?jiǎng)訄D,反正就是可以向下滑
2.2:橫向滑動(dòng)
這塊也和RecyclerView差不多
在layout.item里面加入:
android:orientation="vertical"在活動(dòng)中加一句
viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);更簡單了
3:RecyclerView和ViewPager2的異同點(diǎn)
| 不同點(diǎn) | RecyclerView需要實(shí)例化布局,而ViewPager2不需要 | 正因?yàn)镽ecyclerView布局需要實(shí)例化,ViewPager2不需要,所以RecyclerView的實(shí)現(xiàn)左右滑動(dòng)要稍微比ViewPager2麻煩 |
4.ViewPager2與Fragment聯(lián)動(dòng)效果
其實(shí)在寫ViewPager2的時(shí)候我就在想,當(dāng)用ViewPager2時(shí),能不能實(shí)現(xiàn)無限滑動(dòng)的效果
我想的是在MainActivity的init()方法里面,在for循環(huán)中加一句(因?yàn)槲业膇是從0開始,等于3的時(shí)候結(jié)束),i=3時(shí),i又等于了0,感覺沒問題,覺得可以實(shí)現(xiàn)這個(gè)功能,但是直接應(yīng)用閃退。
突然想了一下,應(yīng)該是因?yàn)閂iewPager2的回收機(jī)制
,然后突然發(fā)現(xiàn),ViewPager2與Fragment聯(lián)動(dòng)好像可以解決這個(gè)問題
Fragment是Activity的一部分,或者頁面的一部分,當(dāng)頁面上的內(nèi)容太多需要針對(duì)性加載時(shí)可以采用Fragment;ViewPager2是管理多個(gè)Fragment的工具.
4.1:水平翻頁
先在MainActivity所在的包下建立一個(gè)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"><TextViewandroid:id="@+id/mTextView"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="36sp"android:gravity="center"/><TextViewandroid: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_NUMBERprivate static final String ARG_PARAM1 = "param1";private static final String ARG_PARAM2 = "param2";// TODO: Rename and change types of parametersprivate 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 parameterspublic 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;}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (getArguments() != null) {mParam1 = getArguments().getString(ARG_PARAM1);mParam2 = getArguments().getString(ARG_PARAM2);}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_blank, container, false);} }這是剛才建立Fragment(Blank)時(shí)自動(dòng)補(bǔ)充的代碼
onCreate()上面的方法基本上用不著可以先不看
onCreate()里面的代碼基本不用改
但是為了方便觀察,我們?cè)诶锩婕由?strong>Log.d
public static BlankFragment newInstance(String param1, String param2) {Log.d("BlankFragment","newInstance: 從主函數(shù)那邊調(diào)過來創(chuàng)建碎片的實(shí)例");BlankFragment fragment = new BlankFragment();Bundle args = new Bundle();args.putString(ARG_PARAM1, param1);args.putString(ARG_PARAM2, param2);fragment.setArguments(args);return fragment;}@Overridepublic void onCreate(Bundle savedInstanceState) {Log.d("BlankFragment","onCreate: 在這里創(chuàng)建碎片");super.onCreate(savedInstanceState);if (getArguments() != null) {mParam1 = getArguments().getString(ARG_PARAM1);mParam2 = getArguments().getString(ARG_PARAM2);}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {Log.d("BlankFragment","onCreateView: 在這里加載視圖");// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_blank, container, false);}引入一個(gè)View方便后面的操作
View rootView; public static BlankFragment newInstance(String param1, String param2) {Log.d("BlankFragment","newInstance: 從主函數(shù)那邊調(diào)過來創(chuàng)建碎片的實(shí)例");BlankFragment fragment = new BlankFragment();Bundle args = new Bundle();args.putString(ARG_PARAM1, param1);args.putString(ARG_PARAM2, param2);fragment.setArguments(args);return fragment;}@Overridepublic void onCreate(Bundle savedInstanceState) {Log.d("BlankFragment","onCreate: 在這里創(chuàng)建碎片");super.onCreate(savedInstanceState);if (getArguments() != null) {mParam1 = getArguments().getString(ARG_PARAM1);mParam2 = getArguments().getString(ARG_PARAM2);}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {Log.d("BlankFragment","onCreateView: 在這里加載視圖");// Inflate the layout for this fragmentif(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:創(chuàng)建構(gòu)造器
再創(chuàng)建一個(gè)適配器
public class MyAdapter extends FragmentStateAdapter { }這時(shí)候它會(huì)提示你,讓你重寫2個(gè)方法,分別是
@NonNull @Override public Fragment createFragment(int position) {return null; }@Override public int getItemCount() {return 0; }并且讓你寫出它的構(gòu)造方法
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: 這是那個(gè)適配器的構(gòu)造函數(shù)");this.fragments = fragments;Log.d(TAG, "MyAdapter: "); }@NonNull @Override public Fragment createFragment(int position) {Log.d(TAG, "createFragment: 看看這是第幾個(gè)視圖" + 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.ViewPager2android: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<>();@Overrideprotected 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"));} }向右滑動(dòng)的效果
4.2:和TabLayout聯(lián)動(dòng)
首先先在MainActivity的layout里面加上
<com.google.android.material.tabs.TabLayoutandroid: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() {@Overridepublic 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");}效果如圖
可以通過按下面的鍵實(shí)現(xiàn)跳躍
4.3:ViewPager2+Fragment實(shí)現(xiàn)從最后一頁滑到第一頁
適配器里面的東西完全不用改變
在MainActivity里面加上
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {@Overridepublic 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");}至于為什么這么寫呢,我只能說這是我為數(shù)不多會(huì)的了
和那種真正的輪流播放還是存在一定的差距的,你會(huì)發(fā)現(xiàn)和上面那張圖比起來,TabLayout里面多了1個(gè)5
我的想法就是多弄了一個(gè)ViewPager2,最后一個(gè)ViewPager2和第一個(gè)Viewpager2設(shè)置的一摸一樣,當(dāng)它的TabLayout的值為4的時(shí)候,就已經(jīng)進(jìn)行到第5個(gè)ViewPager2了,這時(shí)候直接跳回到第一個(gè)ViewPager2就實(shí)現(xiàn)了這個(gè)
至于為什么要把最后一個(gè)和第一個(gè)設(shè)置成一樣的,那是因?yàn)槿绻野?strong>TabLayout去掉的話,就不容易看出來我寫了5個(gè)ViewPager2而只會(huì)以為我寫了4個(gè)
總結(jié)
以上是生活随笔為你收集整理的RecyclerView与ViewPager2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式:UML类图、策略模式、单例模式
- 下一篇: 性能分析之排队论应用