Android應(yīng)用開發(fā)時(shí)耍贾,我們經(jīng)常會(huì)碰到一個(gè)Activity內(nèi)使用ViewPager包含多個(gè)Fragment的情況医增。由于ViewPager的預(yù)加載功能奕纫,通過setOffscreenPageLimit(int number) 來(lái)設(shè)置預(yù)加載署惯,默認(rèn)的預(yù)加載是1,但是即使你設(shè)置為0延刘,也是不起作用的漫试,設(shè)置的只能是大于1才會(huì)有效果。這無(wú)疑會(huì)為性能上帶來(lái)很大影響碘赖。解決這個(gè)問題有兩種方式驾荣,一種是禁止ViewPager的預(yù)加載,重寫ViewPager,但是該方法會(huì)出現(xiàn)左右滑動(dòng)時(shí)會(huì)出現(xiàn)卡頓現(xiàn)象普泡,帶來(lái)不好的用戶體驗(yàn)播掷。而另外一種就是我們接下來(lái)要講的通過Fragment的懶加載來(lái)實(shí)現(xiàn)。當(dāng)用戶切換到某個(gè)fragment時(shí)再加載撼班。
通過查看Fragment的源碼可以發(fā)現(xiàn)它有setUserVisibleHint()這個(gè)方法歧匈,源碼如下:
/** * 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),這個(gè)Fragment的UI是否是可見的砰嘁。所以我們只需要繼承Fragment并重寫該方法眯亦,即可實(shí)現(xiàn)在fragment可見時(shí)才進(jìn)行數(shù)據(jù)加載操作,即Fragment的懶加載般码。
使用時(shí),寫一個(gè)基類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中增加了三個(gè)方法券时,一個(gè)是onVisible ,當(dāng)fragment可見時(shí)調(diào)用孤里。一個(gè)是onInvisible,當(dāng)fragment不可見時(shí)調(diào)用。另外一個(gè)是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可見時(shí)虏等,先進(jìn)入loadData方法,當(dāng)判斷各控件未初始化完畢适肠,則進(jìn)入onCreateView方法霍衫,當(dāng)控件初始化完畢后,會(huì)再次調(diào)用loadData侯养。在loadData中判斷isPrepared和isVisible,只要有一個(gè)不為true就不往下執(zhí)行敦跌。因此,只有初始化完成并且fragment可見情況下逛揩,才會(huì)加載數(shù)據(jù)柠傍,這樣就避免了未初始化帶來(lái)的問題。
在這里感謝提供的幫助貌似掉線
版權(quán)聲明:本文為博主原創(chuàng)文章辩稽,未經(jīng)博主允許不得轉(zhuǎn)載惧笛。