Fragment懶加載

在ViewPager與Fragment一起使用時(shí),由于ViewPager的特性,F(xiàn)ragment會(huì)預(yù)加載,但是我們希望只在當(dāng)前界面時(shí)才加載數(shù)據(jù)。


基類:

public abstract class LazyFragment extends Fragment {
    //當(dāng)前Fragment是否可見
    protected boolean isVisible;
    /**
     * 在這里實(shí)現(xiàn)Fragment數(shù)據(jù)的緩加載.
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }

    protected void onVisible(){
        lazyLoad();
    }

    protected abstract void lazyLoad();

    protected void onInvisible(){}
}

子類Fragment:

//思想:當(dāng)不可見時(shí)只inflate布局(且只inflate一次),
// 可見時(shí)去加載數(shù)據(jù),只加載一次,滑動(dòng)下一個(gè)再回來時(shí)就不去加載數(shù)據(jù)了,除非手動(dòng)刷新(或者Fragment被回收)
public class MyFragment1 extends LazyFragment {
    //布爾的默認(rèn)值是false

    // 標(biāo)志位,標(biāo)志已經(jīng)初始化完成。(是否已經(jīng)inflat布局以及findviewById了)
    private boolean isPrepared;
    private TextView rootView;
    /**
     * 是否已加載過一次數(shù)據(jù)(可能走網(wǎng)絡(luò)),第二次就不再去請(qǐng)求數(shù)據(jù)了
     */
    private boolean mHasLoadedDataOnce;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d("alan", "MyFragment1  oncreateView");
        if (rootView == null) {
            Log.d("alan", "init rootView");
            rootView = new TextView(getActivity());
            //... 初始化各種控件(findViewById)

            isPrepared = true;
            lazyLoad();
        }
        //因?yàn)楣灿靡粋€(gè)Fragment視圖,所以當(dāng)前這個(gè)視圖已被加載到Activity中,必須先清除后再加入Activity
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null) {
            parent.removeView(rootView);
        }
        return rootView;
    }

    //必須先inflate過布局,才能去加載數(shù)據(jù),注意順序
    @Override
    protected void lazyLoad() {//加載數(shù)據(jù),主要操作都在這里,三個(gè)判斷條件
        Log.d("alan", "isPrepared----->" + isPrepared);
        if (!isPrepared || !isVisible || mHasLoadedDataOnce) {
            return;
        }

        //虛擬一個(gè)加載網(wǎng)絡(luò)數(shù)據(jù)的任務(wù)
        new AsyncTask<Void, Void, Boolean>() {

            private AlertDialog alertDialog;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                //顯示加載進(jìn)度對(duì)話框
                UIHelper.showDialogForLoading(getActivity(),"正在加載...",true);
            }

            @Override
            protected Boolean doInBackground(Void... params) {
                try {
                    Thread.sleep(2000);
                    //走網(wǎng)絡(luò)
                    //doSomething()
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return true;
            }

            @Override
            protected void onPostExecute(Boolean isSuccess) {
                if (isSuccess) {// 加載成功
                    UIHelper.hideDialogForLoading();
                    mHasLoadedDataOnce = true;//加載成功之后才算加載好了一次數(shù)據(jù)

                    //加載數(shù)據(jù)完成后,填充各個(gè)控件
                    rootView.setText(getClass().getName());
                } else {
                    // 加載失敗
                    UIHelper.hideDialogForLoading();

                }
            }
        }.execute();
    }
}

思想梳理:Fragment預(yù)加載時(shí)只加載布局,并且只加載一次,加載完布局并且可見時(shí)才去加載填充數(shù)據(jù)(也只做一次)。
源碼
參考文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容