1. 程式人生 > >Android中Fragment的懶載入

Android中Fragment的懶載入

在大部分安卓APP開發中都會用到ViewPager和Fragment的結合使用,而ViewPager又會出現預載入的情況,比如說開啟app時第一個fragment和第二個fragment已經載入好了,當滑動到第二個fragment的時候第三個fragment已經載入好了,我們大多時候都希望當滑動到哪一頁就載入哪一頁,這樣效能比較好也比較省流量,因此需要一個方法來解決這個問題。

BaseFragment中

import android.support.v4.app.Fragment;

/**
 * Created by AZ001 on 2017/7/6.
 */

public class BaseFragment extends Fragment {

    protected boolean mIsVisible = false;

    /**
     * 在這裡實現懶載入.
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getUserVisibleHint()) {
            mIsVisible = true;
            onVisible();
        } else {
            mIsVisible = false;
            onInvisible();
        }
    }

    protected void onInvisible() {
    }

    /**
     * 顯示時載入資料,需要這樣的使用
     * 注意宣告 isPrepared,先初始化
     * 生命週期會先執行 setUserVisibleHint 再執行onActivityCreated
     * 在 onActivityCreated 之後第一次顯示載入資料,只加載一次
     */
    protected void loadData() {
    }

    protected void onVisible() {
        loadData();
    }
}

在setUserVisibleHint中判斷當前介面是否展示在使用者面前,如果是那麼執行onVisible()方法,否則執行onInvisible()方法

FirstPageFragment

import android.os.Bundle;
import android.support.annotation.Nullable;

/**
 * Created by AZ001 on 2017/7/6.
 */

public class FirstPageFragment extends BaseFragment {

    private boolean isPrepared = false;
    private boolean isFirst = true;


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isPrepared = true;
        //loadData的執行比onActivityCreated快,所以要保證onActivityCreated執行過,再去執行loadData方法,初始化完成後才能執行loadData方法
        //比如當開啟有4個fragment的介面的時候,第一個fragment執行了loadData方法但是還沒有初始化,所以不能執行isParepared為false,
        //然後第一個介面和第二個介面的onActivityCreated已經先執行了,(這裡setOffscreenPageLimit方法設定的數量為預設的)此時isPrepared為true。
        //然後需要手動的去執行loadData方法(因為loadData已經執行了一次之前)。當切換到第二個介面的時候,由於onActivityCreated已經執行過了,初始化已經做好了,那麼
        //BaseFragment 中的onVisible方法會執行,隨後子Fragment中的loadData方法執行了,就不會出現第一個介面開啟時的情況
        loadData();
    }

    @Override
    protected void loadData() {
        //只有當fragment顯示了 初始化完成了 第一次進入介面的時候才能進行資料請求
        if (!mIsVisible || !isPrepared || !isFirst) {
            return;
        }
        //其他操作
    }
}

SecondPageFragment
import android.os.Bundle;
import android.support.annotation.Nullable;

/**
 * Created by AZ001 on 2017/7/6.
 */

public class SecondPageFragment extends BaseFragment {

    private boolean isPrepared = false;
    private boolean isFirst = true;


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isPrepared = true;
        //viewpager的預載入會先執行此方法
    }

    @Override
    protected void loadData() {
        //只有當fragment顯示了 初始化完成了 第一次進入介面的時候才能進行資料請求
        if (!mIsVisible || !isPrepared || !isFirst) {
            return;
        }
        //其他操作
    }
}

在loadData方法中去請求資料,同時要判斷是否展示當前介面,是否已經初始化了,是否已經執行過請求不用每次顯示介面都去請求資料。