Android之Fragment懶加載分析

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)載。

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

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

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