Fragment + ViewPager 之生命週期探索
說到fragment,那我肯定要先上個圖意思一下了。
ViewPager的簡介和作用
ViewPager是android擴充套件包v4包中的類,這個類可以讓使用者左右切換當前的view
1)ViewPager類直接繼承了ViewGroup類,所有它是一個容器類,可以在其中新增其他的view類。
2)ViewPager類需要一個PagerAdapter介面卡類給它提供資料。
3)ViewPager經常和Fragment一起使用,並且提供了專門的FragmentPagerAdapter和FragmentStatePagerAdapter類供Fragment中的ViewPager使用
viewPager還有個特殊屬性 預載入,預設頁面切換時,左右兩側相鄰的頁面會被載入
我們也可以設定預載入頁面的數量,系統預設為1。
mViewPagerm.setOffscreenPageLimit(2);
下面來看程式碼:
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"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_weight="1" android:layout_gravity="center" android:layout_height="0dp"> </android.support.v4.view.ViewPager> </LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private List<Fragment> mListm = new ArrayList<>(); private ViewPager mViewPagerm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mViewPagerm = findViewById(R.id.viewpager); //初始化fragment的例項 Fragment fragment1 = new BlankFragment(); Fragment fragment2 = new BlankFragment1(); Fragment fragment3 = new BlankFragment2(); mListm.add(fragment1); mListm.add(fragment2); mListm.add(fragment3); //為viewpager設定介面卡 mViewPagerm.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return mListm.get(position); } @Override public int getCount() { return mListm.size(); } }); } }
這裡我們設定的介面卡是FragmentPagerAdapter,之後我們會將它和FragmentStatePagerAdapter作比較。
fragment的程式碼我就不貼了,非常簡單。
下面執行程式碼:
題外話,這裡推薦一個手機錄製gif的app:https://zhuanlan.zhihu.com/p/32164908
啟動時為fragment1,fragment2預載入。
切換到fragment2時,fragment3預載入,此時記憶體裡有fragment1,fragment2,fragment3三個物件例項。
切換到fragment3,因為fragment1和fragment3不是相鄰的,viewpager只能預載入左右一個頁面,所以fragment1被系統銷燬。
如果我們將FragmentPagerAdapter換成FragmentStatePagerAdapter時,fragment1會與主activity解除關聯。
所以我們得出結論:
-
FragmentStatePagerAdapter
顧名思義,我們的這個FragmentStatePagerAdapter,在我們切換不同的Fragment的時候,我們會把前面的Fragment銷燬,而我們系統在銷燬前,會把我們的我們Fragment的Bundle在我們的onSaveInstanceState(Bundle)儲存下來。等使用者切換回來的時候,我們的Fragment就會根據我們的instance state恢復出來。 -
FragmentPagerAdapter
使用這種Adapter,我們的Fragment在切換的時候,不會銷燬,而只是呼叫事務中的detach方法,這種方法,我們只會把我們的Fragment的view銷燬,而保留了以前的Fragment物件。所以通過這種方式建立的Fragment一直不會被銷燬。
總結:
講到這裡,相信大家對fragment+viewpager的生命週期有了一定的瞭解了吧!!!