Android應(yīng)用開發(fā)時,我們經(jīng)常會碰到一個Activity內(nèi)使用ViewPager包含多個Fragment的情況。由于ViewPager的預(yù)加載功能,通過setOffscreenPageLimit(int number) 來設(shè)置預(yù)加載,默認(rèn)的預(yù)加載是1,但是即使你設(shè)置為0,也是不起作用的,設(shè)置的只能是大于1才會有效果。這無疑會為性能上帶來很大影響。解決這個問題有兩種方式,一種是禁止ViewPager的預(yù)加載,重寫ViewPager,但是該方法會出現(xiàn)左右滑動時會出現(xiàn)卡頓現(xiàn)象,帶來不好的用戶體驗(yàn)。而另外一種就是我們接下來要講的通過Fragment的懶加載來實(shí)現(xiàn)。當(dāng)用戶切換到某個fragment時再加載。
通過查看Fragment的源碼可以發(fā)現(xiàn)它有setUserVisibleHint()這個方法,源碼如下:
/** * Set a hint to the system about whether this fragment's UI is currently visible
* to the user. This hint defaults to true and is persistent across fragment instance
* state save and restore.
* * <p>An app may set this to false to indicate that the fragment's UI is
* scrolled out of visibility or is otherwise not directly visible to the user.
* This may be used by the system to prioritize operations such as fragment lifecycle updates
* or loader ordering behavior.</p>
* * @param isVisibleToUser true if this fragment's UI is currently visible to the user (default),
* false if it is not. */
public void setUserVisibleHint(boolean isVisibleToUser) {
if(!mUserVisibleHint&& isVisibleToUser && mState < STARED){
mFragmentManager.performPendingDeferredStart(this);
}
mUserVisibleHint = isVisibleToUser;
mDeferStart = !isVisibleToUser;
}
該方法用于告訴系統(tǒng),這個Fragment的UI是否是可見的。所以我們只需要繼承Fragment并重寫該方法,即可實(shí)現(xiàn)在fragment可見時才進(jìn)行數(shù)據(jù)加載操作,即Fragment的懶加載。
使用時,寫一個基類BaseFragment,繼承它即可,代碼如下:
/**
* User: Hlh(tatian91@163.com)
* Date: 2016-07-04
* Time: 09:37
*/
public abstract class BaseFragment extends Fragment {
//是否可見
protected boolean isVisble;
// 標(biāo)志位,標(biāo)志Fragment已經(jīng)初始化完成。
public boolean isPrepared = false;
/**
* 實(shí)現(xiàn)Fragment數(shù)據(jù)的緩加載
* @param isVisibleToUser
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()) {
isVisable = true;
onVisible();
} else {
isVisable = false;
onInVisible();
}
}
protected void onInVisible() {
}
protected void onVisible() {
//加載數(shù)據(jù)
loadData();
}
protected abstract void loadData();
}
在BaseFragment中增加了三個方法,一個是onVisible ,當(dāng)fragment可見時調(diào)用。一個是onInvisible,當(dāng)fragment不可見時調(diào)用。另外一個是loadData。
public class TabFragment extends BaseFragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(LOG_TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_tab, container, false);
//初始化view的各控件
isPrepared = true;
loadData();
return view;
}
@Override
protected void loadData() {
if(!isPrepared || !isVisible) {
return;
}
//填充各控件的數(shù)據(jù)
}
}
Fragment生命周期中,setUserVisbleHint先于onCreateView執(zhí)行。上面實(shí)例中,當(dāng)TabFragment可見時,先進(jìn)入loadData方法,當(dāng)判斷各控件未初始化完畢,則進(jìn)入onCreateView方法,當(dāng)控件初始化完畢后,會再次調(diào)用loadData。在loadData中判斷isPrepared和isVisible,只要有一個不為true就不往下執(zhí)行。因此,只有初始化完成并且fragment可見情況下,才會加載數(shù)據(jù),這樣就避免了未初始化帶來的問題。
在這里感謝提供的幫助貌似掉線
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。