還記得以前使用ViewPager+Fragment時根本不考慮效率問題,一股腦的多頁數(shù)據(jù)加載導致卡死踱卵,還自我安慰說我設置了setOffscreenPageLimit了啊廊驼,而實際上跟蹤源碼我們發(fā)現(xiàn)DEFAULT_OFFSCREEN_PAGES = 1,所以即便setOffscreenPageLimit我設置為0颊埃,ViewPager最少也會加載后一頁蔬充。為了保證效率現(xiàn)在都提倡一種懶加載的機制,即只有當前頁面為顯示頁面才會加載且只加載一次數(shù)據(jù)(做一次耗時操作:或網絡請求或本地數(shù)據(jù))班利。有同學說我可以拷貝源碼把默認改為0啊饥漫,是可以這么做,但是改變了viewpager的初衷罗标,不夠靈活庸队。在實際項目中我還是建議改造BaseFragment,利用setUserVisibleHint闯割,暴露數(shù)據(jù)加載的方法彻消,根據(jù)需要重載懶加載方法做實際操作。
下面來看具體的改造方法:
1.設定兩個標識
private boolean isViewPrepared; // 標識fragment視圖已經初始化完畢
private boolean hasFetchData; // 標識已經觸發(fā)過懶加載數(shù)據(jù)
2.創(chuàng)建懶加載的數(shù)據(jù)加載方法
/** 懶加載的方式獲取數(shù)據(jù)宙拉,僅在滿足fragment可見和視圖已經準備好的時候調用一次 */
protected void lazyFetchData() {
Log.v(TAG, getClass().getName() + "------>lazyFetchData");
}
3.以上兩個標識值的判定:
- 在onViewCreated方法中(即表明視圖已經準備完畢)isViewPrepared = true;
- 在onDestroyView方法中(view被銷毀后宾尚,將可以重新觸發(fā)數(shù)據(jù)懶加載,因為在viewpager下谢澈,fragment不會再次新建并走onCreate的生命周期流程煌贴,將從onCreateView開始)hasFetchData = false; isViewPrepared = false;
4.判定是否需要加載數(shù)據(jù)
private void lazyFetchDataIfPrepared() {
// 用戶可見fragment && 沒有加載過數(shù)據(jù) && 視圖已經準備完畢
if (getUserVisibleHint() && !hasFetchData && isViewPrepared) {
hasFetchData = true; //已加載過數(shù)據(jù)
lazyFetchData();
}
}
5.lazyFetchDataIfPrepared方法的調用時機
- onViewCreated方法中調用lazyFetchDataIfPrepared方法,此時只有首頁會符合條件
- setUserVisibleHint
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
Log.v(TAG, getClass().getName() + "------>isVisibleToUser = " + isVisibleToUser);
if (isVisibleToUser) {//當當前為顯示頁面時
lazyFetchDataIfPrepared();
}
}
6.子類Fragment根據(jù)需要重載lazyFetchData方法(訪問網絡加載數(shù)據(jù))
@Override
protected void lazyFetchData() {
((DiscoverPresenter) mPresenter).getData();
}
整個改造就算結束了锥忿,是不是很簡單牛郑,為了讓你的fragment不那么累趕緊試試吧(如果還有不懂可以參照源碼)。
qq交流群:138485840
下載地址:微影
源碼地址:Ghost
歡迎大家下載和Star