使用Fragment懶加載的一種方式

在很多應用中,首頁都是由三個或四個Fragment構(gòu)成,且都是上中下結(jié)構(gòu)。這種設計方式大行其道,但是作為首頁,每一個Fragment的內(nèi)容肯定是較多的,這個時候直接加載出來,或是默認加載兩三個都是有點耗費資源的,特別是在打開應用的時候,如果操作過多可能會卡,所以很多應用在首頁都會使用Fragment懶加載,例如微信。

對于如何懶加載,也算是Android中比較簡單的內(nèi)容,本文只是針對這個問題提供一種比較通用的解決方法。如果你對Android開發(fā)比較熟悉的話,不要讓本文浪費你的時間。如果你閱讀本文,你將會學習如下內(nèi)容:

  • Fragment 中 setUserVisibleHint 函數(shù)
  • 上中下結(jié)構(gòu)的首頁設計實現(xiàn)
  • Fragment 懶加載的一種實現(xiàn)方式

本文中代碼可在此處查看:https://github.com/Lee-swifter/LazyFragmentDemo


一,創(chuàng)建懶加載基類Fragment

這個函數(shù)簡單來說就是用來表明該Fragment是否向用戶展示,如果用戶能夠看到該Fragment,那么這個函數(shù)的參數(shù)則為true。說起來簡單,但是這個函數(shù)有個特別需要注意的地方就是此函數(shù)不是生命周期函數(shù)。也就是說,該方法有可能在脫離生命周期的地方調(diào)用,例如當Fragment還沒有onCreateView時,這個函數(shù)就有可能調(diào)用,而此時如果控制界面的話,就會出現(xiàn)NullPointerException。在進行懶加載的處理時,這一點需要特別照顧。

在這種懶加載方式中,先創(chuàng)建一個LazyFragment實現(xiàn)懶加載的所有操作,然后再創(chuàng)建其子類作為實際使用。這樣的話,只要是繼承自這個LazyFragment的Fragment就會具有懶加載的功能,方便實際使用。

1. 首先,為了進行懶加載,設定幾個標志:

private boolean hasLoaded = false;  //標識是否已經(jīng)加載過
private boolean hasCreated = false; //標識onCreateView是否已調(diào)用
private boolean needInit = false;   //標識是否需要在onCreateView中

2. 在setUserVisibleHint中進行判斷處理

if (isVisibleToUser && !hasLoaded) {    //如果當前Fragment向用戶展示且沒有加載過,進行下一步判斷
    if (hasCreated) {   //如果onCreateView已經(jīng)被創(chuàng)建,此時進行加載
        initWrapper();
    } else {        //如果Fragment沒有創(chuàng)建,那么設置標記,在onCreateView中加載
        needInit = true;
    }
}

此處進行的一些判斷操作就是為了處理此函數(shù)在Fragment還沒有創(chuàng)建界面時的情況。如果出現(xiàn)了這種情況,那么設置標記位在onCreateView中加載。其中initWrapper函數(shù)來進行加載界面,而此時加載的僅僅為該LazyFragment的界面,只包含一個ProgressBarFramentLayout。其中ProgressBar僅僅為加載之前的展示,而FramentLayout則是用來放置其子類布局的。

private void initWrapper() {
    LayoutInflater.from(getContext()).inflate(setContentView(), content);
    initialize();
    fadeOutView(progressBar, mShortAnimationDuration);
    fadeInView(content, mShortAnimationDuration);
    hasLoaded = true;
}

3. 創(chuàng)建子類使用的函數(shù)

/**
 * 供子類使用,子類fragment初始化操作,此函數(shù)內(nèi)部真正開始進行頁面的一些列操作
 */
abstract void initialize();

/**
 * 子類fragment設置布局,返回fragment要設定的布局
 * @return 子類fragment要顯示的布局
 */
@LayoutRes
abstract int setContentView();

上面基本都是創(chuàng)建Fragment懶加載基類重點的地方,其子類只需要復寫上面兩個函數(shù)就可以以懶加載的方式使用。其他內(nèi)容可以使用查看項目倉庫。

二,創(chuàng)建懶加載子類Fragment

其實只要實現(xiàn)了基類,那么懶加載框架就已經(jīng)基本完成,繼承子類只是來使用,這個地方是比創(chuàng)建其基類要容易很多。創(chuàng)建其子類只需要復寫這兩個函數(shù),這樣就可以作為一個普通的Fragment來使用:

@Override
void initialize() {
    //用來進行本Fragment的初始化操作
}

@Override
int setContentView() {
    return R.layout.fragment;   //返回本類所的布局
}

三,創(chuàng)建使用懶加載Fragments的Activity

一般來說使用標簽頁的Activity,都是上中下結(jié)構(gòu),上面Toolbar,中間FrameLayou用來顯示內(nèi)容,下面就是 Bottom Navigation Tab。這種實現(xiàn)并沒有什么難度,也有很多種實現(xiàn)方式,特別是底部導航欄。而在中間,本例子種使用的是ViewPager,這樣可以實現(xiàn)左右滑動切換,也是微信的加載方式。其中代碼與Fragment懶加載無關(guān),所以就不再贅述。

在具體代碼倉庫中,實現(xiàn)了這種懶加載的這種方式,如有需要的可以去看看:https://github.com/Lee-swifter/LazyFragmentDemo

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

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

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