在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ù)(也只做一次)。
源碼
參考文章