Android開發丶使用懶載入修復tablayout+viewpager+fragment的預載入

Fantasychong丶發表於2017-05-09

何為預載入:

因為該處使用到了Fragment+Viewpager+Tablayout的組合實現分類,因為viewpager V4包的機制,導致了在載入一個fragment時候,預設會載入它左右兩邊的兩個fragment,原始碼顯示是通過viewpager.setoffscreenpagelimit(1)來控制預載入的fragment的數量,該處預設最小值就是1,設為0並無效果,因此從原始碼端取消預載入是行不通的,經過多方調研,通過下面的方法可實現效果


首先新建一個BaseFragment基類,如下:

public abstract class BaseFragment extends Fragment {

    public    Context mContext;

    protected View    view;

    protected boolean isVisible;

    /**

     * 是否初始檢視完成

     */

    private   boolean isPrepared;

    @Override

    public void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mContext = getActivity();

    }

    @Nullable

    @Override

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        view = bindLayout(inflater);

        initView();

        return view;

    }

    @Override

    public void onActivityCreated(@Nullable Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);

        //這裡 初始化view的各控制元件 資料

        isPrepared = true;

        lazyLoad();

    }

    /**

     * setUserVisibleHint是在onCreateView之前呼叫的

     *

     * @param isVisibleToUser

     */

    @Override

    public void setUserVisibleHint(boolean isVisibleToUser) {

        super.setUserVisibleHint(isVisibleToUser);

        /**

         * 判斷是否可見

         */

        if(getUserVisibleHint()) {

            isVisible = true;

            //執行可見方法-初始化資料之類

            onVisible();

        } else {

            isVisible = false;

            //不可見

            onInvisible();

        }

    }

    /**

     * 可見做懶載入

     */

    private void onVisible() {

        lazyLoad();

    }

    /**

     * 懶載入

     */

    private void lazyLoad() {

        /**

         * 判斷是否可見,或者 初始化view的各控制元件

         */

        if(!isVisible || !isPrepared) {

            return;

        }

        //可見 或者 控制元件初始化完成 就 載入資料

        initData();

    }

    /**

     * 不可見-做一些銷燬工作

     */

    protected void onInvisible() {

    }

    /**

     * 繫結佈局

     *

     * @param inflater

     * @return

     */

    public abstract View bindLayout(LayoutInflater inflater);

    /**

     * 初始化佈局

     */

    public abstract void initView();

    /**

     * 初始化資料

     */

    protected abstract void initData();

}

該基類Fragment核心方法為:

setUserVisibleHint,在該方法中判斷目標fragment是否可見,當可見的時候執行元件初始化和資料讀取

在目標Fragment繼承BaseFragment

重寫這三個方法


這樣就解決了預載入導致的衝突問題!

相關文章