Fragment懶加載

github地址

https://github.com/zhouxu88/LazyFragment.git

一、簡介

?????玩過微信的都知道,微信用的是懶加載的模式,之所以使用懶加載是因為:當(dāng)使用viewpager+adapter作為應(yīng)用大的布局時,viewpager會通過setOffscreenPageLimit來設(shè)置預(yù)加載的項目,不設(shè)置setOffscreenPageLimit,則默認(rèn)為1(設(shè)置0無效,可以查看該方法源碼知道),也就是當(dāng)我們打開應(yīng)用看到的時候fragmentOne時,實際上其他fragment(例如fragmentSecond)也進行了加載,只不過沒有顯示出來罷了,但是這樣就造成了不必要的資源浪費(例如,fragmentSecond沒有顯示,但是卻進行了大量的網(wǎng)絡(luò)加載操作)。

在此先要說下一下幾個方法:
1.ViewPager中的setOffscreenPageLimit方法,設(shè)置預(yù)加載的頁面?zhèn)€數(shù),參數(shù)不能小于1因為默認(rèn)最小就是1。作用是:可以讓Fragment視圖不會被銷毀。

2.Fragment中的setUserVisibleHint方法,當(dāng)參數(shù)為true時對用戶可見,當(dāng)為false時對用戶不可見(這是懶加載的關(guān)鍵所在

二、使用步驟

1、LazyFragment:

/**
 * A simple {@link Fragment} subclass.
 * "懶加載"的Fragment的基類
 */
public abstract class LazyFragment extends Fragment {


    private View view;

    private boolean needInit;      //是否需要在onCreateView中初始化組件
    private boolean hasLoad;      //標(biāo)識是否已經(jīng)加載過
    private boolean hasCreated;  //是否為第一次加載數(shù)據(jù)

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //展示 & 沒有加載過
        if (isVisibleToUser && !hasLoad) {
            //如果當(dāng)前Fragment向用戶展示且沒有加載過,進行下一步判斷
            if (hasCreated) {
                //如果onCreateView已經(jīng)被創(chuàng)建,此時進行加載
                initView();
            } else {
                //如果Fragment沒有創(chuàng)建,那么設(shè)置標(biāo)記,在onCreateView中加載
                needInit = true;
            }
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(getLayoutId(), container, false);
        if (needInit) {
            //是否要初始化,后面頁不需要
            initView();
            needInit = false;
        }
        hasCreated = true;
        return view;
    }

    private void initView() {
        init(view);
        hasLoad = true;
    }

    //獲取Fragment的布局文件
    @LayoutRes
    protected abstract int getLayoutId();

    //包含初始化數(shù)據(jù)
    protected abstract void init(View view);

}

2、所有Fragment子類繼承于LazyFragment

public class ShopCartFragment extends LazyFragment {

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_shop_cart;
    }

    //初始化View和數(shù)據(jù)
    @Override
    protected void init(View view) {

        //初始化View
        initView();

        //初始化數(shù)據(jù)
        initData();
    }

3、Activity中注意

//設(shè)置預(yù)加載頁面的數(shù)目,避免當(dāng)頁面?zhèn)€數(shù) > 3時,有Fragment被銷毀的情況
viewPager.setOffscreenPageLimit(mList.size() - 1);

4、另一個懶加載的Fragment的基類

public abstract class BaseFragment extends Fragment {

    private boolean isVisible = false;//當(dāng)前Fragment是否可見
    private boolean isInitView = false;//是否與View建立起映射關(guān)系
    private boolean isFirstLoad = true;//是否是第一次加載數(shù)據(jù)

    private View convertView;
    private SparseArray<View> mViews;

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        LogUtil.m("isVisibleToUser " + isVisibleToUser + "   " + this.getClass().getSimpleName());
        if (isVisibleToUser) {
            isVisible = true;
            lazyLoadData();

        } else {
            isVisible = false;
        }
        super.setUserVisibleHint(isVisibleToUser);
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        LogUtil.m("   " + this.getClass().getSimpleName());
        convertView = inflater.inflate(getLayoutId(), container, false);
        mViews = new SparseArray<>();
        initView();
        isInitView = true;
        lazyLoadData();
        return convertView;
    }

    private void lazyLoadData() {
        if (isFirstLoad) {
            LogUtil.m("第一次加載 " + " isInitView  " + isInitView + "  isVisible  " + isVisible + "   " + this.getClass().getSimpleName());
        } else {
            LogUtil.m("不是第一次加載" + " isInitView  " + isInitView + "  isVisible  " + isVisible + "   " + this.getClass().getSimpleName());
        }
        if (!isFirstLoad || !isVisible || !isInitView) {
            LogUtil.m("不加載" + "   " + this.getClass().getSimpleName());
            return;
        }

        LogUtil.m("完成數(shù)據(jù)第一次加載"+ "   " + this.getClass().getSimpleName());
        initData();
        isFirstLoad = false;
    }

    /**
     * 加載頁面布局文件
     * @return
     */
    protected abstract int getLayoutId();

    /**
     * 讓布局中的view與fragment中的變量建立起映射
     */
    protected abstract void initView();

    /**
     * 加載要顯示的數(shù)據(jù)
     */
    protected abstract void initData();

    /**
     * fragment中可以通過這個方法直接找到需要的view,而不需要進行類型強轉(zhuǎn)
     * @param viewId
     * @param <E>
     * @return
     */
    protected <E extends View> E findView(int viewId) {
        if (convertView != null) {
            E view = (E) mViews.get(viewId);
            if (view == null) {
                view = (E) convertView.findViewById(viewId);
                mViews.put(viewId, view);
            }
            return view;
        }
        return null;
    }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容