1. 程式人生 > >Fragment + ViewPager 之生命週期探索

Fragment + ViewPager 之生命週期探索

說到fragment,那我肯定要先上個圖意思一下了。

â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的生命週期有了一定的瞭解了吧!!!