昨天項目剛上線,今天產品又要改需求...........
利用一點空隙時間整理了一下ViewPager2的使用
效果圖
由於當前項目中用的懶加載 LazyViewPager 是別人開源的,時間也很久了並且現在使用發現了一些bug,配合 TabLayout使用,在頁面初始化後,你從第一頁點到第三頁或者第四頁有時候會出現當前頁面加載空白問題!由於前段時間項目緊急就一直沒有修改,現在剛上線就趕緊修改一下。
網上一搜都是自定義LazyFragment ,通過 getUserVisibleHint() 獲取是否可見來封裝處理,自己實現數據的懶加載,這樣完全沒問題,但是咱不是懶啊,聽說新出來一個 ViewPager2,就新建來一個項目嘗試一下。
新建項目是 AndroidX 項目,不是AndroidX 請繞行。
建好項目後 導入依賴
//ViewPager2的依賴
implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha01'
//配合 TabLayout使用 所用到的相關輔助類
implementation "com.google.android.material:material:1.1.0"
順便說一下我的 minSdkVersion 是22的
編譯後開始上手敲代碼
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"
android:orientation="vertical"
tools:context=".MainActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/mTabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/mViewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java
package com.wavewave.viewpager2;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.wavewave.viewpager2.fragment.BlankFragment;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<Fragment> fragmentList = new ArrayList<>();
private String[] titles = {"1", "2", "3", "4", "5"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
ViewPager2 mViewPager2 = findViewById(R.id.mViewPager2);
TabLayout mTabLayout = findViewById(R.id.mTabLayout);
fragmentList.add(BlankFragment.newInstance("1", ""));
fragmentList.add(BlankFragment.newInstance("2", ""));
fragmentList.add(BlankFragment.newInstance("3", ""));
fragmentList.add(BlankFragment.newInstance("4", ""));
fragmentList.add(BlankFragment.newInstance("5", ""));
mViewPager2.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList.size();
}
});
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(mTabLayout, mViewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(titles[position]);
}
});
tabLayoutMediator.attach();
}
}
然後 fragment_blank.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".fragment.BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/mTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
BlankFragment.java
package com.wavewave.viewpager2.fragment;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.wavewave.viewpager2.R;
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);
}
Log.d("aaaaaa", "onCreate" + mParam1);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank, container, false);
initView(view);
return view;
}
private void initView(View view) {
Log.d("aaaaaa", "initView" + mParam1);
TextView mTextView = view.findViewById(R.id.mTextView);
mTextView.setText(mParam1);
Toast.makeText(getActivity(), "我要調接口了!" + mParam1, Toast.LENGTH_SHORT).show();
}
@Override
public void onResume() {
super.onResume();
Log.d("aaaaaa", "onResume" + mParam1);
}
@Override
public void onPause() {
super.onPause();
Log.d("aaaaaa", "onPause" + mParam1);
}
}
運行起來發現 初始化時候的生命週期
可以看到只加載第一個頁面的數據了,然後滑動到第二頁只加載第二頁的數據,再滑回到第一頁,第一頁初始化加載數據不會重新走。
當然生命週期還是會走的
搞定!替換代碼下班,下班。
發現當你的fragment多的時候,大於等於4個的時候它就會重新加載邊緣的一個了。
也就是說它默認會保持3個fragment的生命週期不會重新走。目前我是夠用了,等後面再研究研究!