實現ViewPager懶載入的三種方法
在專案中ViewPager和Fragment介面框架已經是處處可見,但是在使用中,我們肯定不希望使用者在當前頁面時就在前後頁面的資料,加入資料量很大,而使用者又不願意左右滑動瀏覽,那麼這時候ViewPager中本來充滿善意的預載入就有點令人不爽了。我們能做的就是遮蔽掉ViewPager的預載入機制。雖然ViewPager中提供的有
setOffscreenPageLimit()來控制其預載入的數目,但是當設定為0後我們發現其根本沒效果,這個的最小值就是1,也就是你只能最少前後各預載入一頁。那麼,這時候就得另覓方法了。
以下三種方法是我在學習和專案中嘗試過的,需求實現了,但各有千秋,可結合不同場景使用。因為打算慢慢養成寫部落格的習慣,就總結在此,也希望對他人有所借鑑。
方法一
在Fragment可見時請求資料。此方案仍預載入了前後的頁面,但是沒有請求資料,只有進入到當前Framgent時才請求資料。
優點:實現了資料的懶載入
缺點:一次仍是三個Framgment物件,不是完全意義的懶載入
publicclassFragmentSampleextendsFragment{
...
@Override
publicvoid setUserVisibleHint(boolean isVisibleToUser){
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
requestData
}
}
...
}
方法二
直接修改ViewPager原始碼。通過檢視ViewPager原始碼可知,控制其預載入的是一個常量
DEFAULT_OFFSCREEN_PAGES,其預設值為1,表示當前頁面前後各預載入一個頁面,在這裡我們直接將其設定為0即可,即去掉預載入。但是,這樣有一個問題,那就是在使用其他控制元件時需要傳入ViewPager時,這個就不能用了。
優點:完全遮蔽掉了預載入
缺點:應用太受限制,比如使用ViewPagerIndicator時需要傳入ViewPager物件,這時傻眼了。
// 注意,這是直接拷貝的ViewPager的原始碼,只修改了註釋處的程式碼
public class LazyViewPager extends ViewGroup {
private static final String TAG = "LazyViewPager";
private static final boolean DEBUG = false;
private static final boolean USE_CACHE = false;
// 預設為1,即前後各預載入一個頁面,設定為0去掉預載入
private static final int DEFAULT_OFFSCREEN_PAGES = 0;
private static final int MAX_SETTLE_DURATION = 600; // ms
static class ItemInfo {
Object object;
int position;
boolean scrolling;
}
private static final Comparator<ItemInfo> COMPARATOR = new Comparator<ItemInfo>() {
@Override
public int compare(ItemInfo lhs, ItemInfo rhs) {
return lhs.position - rhs.position;
}
};
............
}
方法三
直接繼承ViewPager,結合PagerAdapter實現懶載入。該方案是我用到的最完善的方法,完全的懶載入,每次只會建立一個Fragment物件。
優點:完全遮蔽預載入
缺點:稍微複雜,但是人家已經造好的輪子,直接用吧,很簡潔
這個庫就4個類,作者通過繼承ViewPager(保證其普適性)、自定義ViewPagerAdapter和 LazyFragmentPagerAdapter以及設定懶載入的標記介面,很好的實現了懶載入。感謝作者。
在此貼出關鍵程式碼,有興趣的同學可以學習下。
LazyViewPager:
publicclassLazyViewPagerextendsViewPager{
privatestaticfinalfloat DEFAULT_OFFSET =0.5f;
privateLazyPagerAdapter mLazyPagerAdapter;
privatefloat mInitLazyItemOffset = DEFAULT_OFFSET;
publicLazyViewPager(Context context){
super(context);
}
publicLazyViewPager(Context context,AttributeSet attrs){
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LazyViewPager);
setInitLazyItemOffset(a.getFloat(R.styleable.LazyViewPager_init_lazy_item_offset, DEFAULT_OFFSET));
a.recycle();
}
/**
* change the initLazyItemOffset
* @param initLazyItemOffset set mInitLazyItemOffset if {@code 0 < initLazyItemOffset <= 1}
*/
publicvoid setInitLazyItemOffset(float initLazyItemOffset){
if(initLazyItemOffset >0&& initLazyItemOffset <=1){
mInitLazyItemOffset = initLazyItemOffset;
}
}
@Override
publicvoid setAdapter(PagerAdapter adapter){
super.setAdapter(adapter);
mLazyPagerAdapter = adapter !=null&& adapter instanceofLazyPagerAdapter?(LazyPagerAdapter) adapter :null;
}
@Override
protectedvoid onPageScrolled(int position,float offset,int offsetPixels){
if(mLazyPagerAdapter !=null){
if(getCurrentItem()== position){
int lazyPosition = position +1;
if(offset >= mInitLazyItemOffset && mLazyPagerAdapter.isLazyItem(lazyPosition)){
mLazyPagerAdapter.startUpdate(this);
mLazyPagerAdapter.addLazyItem(this, lazyPosition);
mLazyPagerAdapter.finishUpdate(this);
}
}elseif(getCurrentItem()> position){
int lazyPosition = position;
if(1- offset >= mInitLazyItemOffset && mLazyPagerAdapter.isLazyItem(lazyPosition)){
mLazyPagerAdapter.startUpdate(this);
mLazyPagerAdapter.addLazyItem(this, lazyPosition);
mLazyPagerAdapter.finishUpdate(this);
}
}
}
super.onPageScrolled(position, offset, offsetPixels);
}
}
publicabstractclassLazyFragmentPagerAdapterextendsLazyPagerAdapter<Fragment>{
privatestaticfinalString TAG ="LazyFragmentPagerAdapter";
privatestaticfinalboolean DEBUG =false;
privatefinalFragmentManager mFragmentManager;
privateFragmentTransaction mCurTransaction =null;
publicLazyFragmentPagerAdapter(FragmentManager fm){
mFragmentManager = fm;
}
@Override
publicvoid startUpdate(ViewGroup container){
}
@Override
publicObject instantiateItem(ViewGroup container,int position){
if(mCurTransaction ==null){
mCurTransaction = mFragmentManager.beginTransaction();
-
相關推薦
實現ViewPager懶載入的三種方法
在專案中ViewPager和Fragment介面框架已經是處處可見,但是在使用中,我們肯定不希望使用者在當前頁面時就在前後頁面的資料,加入資料量很大,而使用者又不願意左右滑動瀏覽,那麼這時候ViewPager中本來充滿善意的預載入就有點令人不爽了。我們能做的就是遮蔽掉View
Python實現下載檔案的三種方法
下面來看看三種方法是如何來下載zip檔案的:方法一: import urllib print "downloading with urllib" url = 'http://www.jb51.net//test/demo.zip' urllib.urlretrieve(url, "demo.zip")
vue webpack 懶載入三種方式
const router = new Router({ routes: [ { path:
vue+element ui專案總結點(一)select、Cascader級聯選擇器、encodeURI、decodeURI轉碼解碼、一級mockjs用法、路由懶載入三種方式
不多說上程式碼: <template> <div class="hello"> <h1>{{ msg }}</h1> <p>Element UI簡單Cascader級聯選擇器使用</p> <
Java實現ping功能的三種方法
檢測裝置的執行狀態,有的是使用ping的方式來檢測的。所以需要使用java來實現ping功能。 為了使用java來實現ping的功能,有人推薦使用java的 Runtime.exec()方法來直接呼叫系統的Ping命令,也有人完成了純Java實現Ping的程式,使用的是Jav
Nginx實現404頁面的三種方法
一個網站專案,肯定是避免不了404頁面的,通常使用Nginx作為Web伺服器時,有以下集中配置方式: 第一種:Nginx自己的錯誤頁面 Nginx訪問一個靜態的html 頁面,當這個頁面沒有的時候,
java實現動態代理的三種方法
緒論:以下三種java實現動態代理的的方式,分別為基於jdk的,基於cglib的和基於javassist的,其中需要注意的兩點 一:基於jdk實現的動態代理需要實現父類,而其他兩種不需要 二:其中基於cglib的需要額外的jar包依賴,pom的依賴如下 <!-- https://m
Android移動開發 實現按鈕機制的三種方法
Android開發中有三種主要的方式用於設定View的點選事件,1、建立內部類;2、主類中實現OnClickListener介面;3、使用匿名內部類。這三種方式都用到了OnClickListener介面,只是不同形式而已。其中OnClickListener是監
MyBatis實現模糊查詢的三種方法
模糊查詢也是資料庫SQL中使用頻率很高的SQL語句,使用MyBatis來進行更加靈活的模糊查詢。 直接傳參法 直接傳參法,就是將要查詢的關鍵字keyword,在程式碼中拼接好要查詢的格式,如%keyword%,然後直接作為引數傳入mapper.xml的對映檔案中。在查詢前
Android實現資料持久化的三種方法
考慮下面幾種情況: 使用者對應用的亮度、音量、字型顏色等進行了配置; 使用者在遊戲過程中打出了新的記錄; 使用者使用應用下載了一些圖片、音樂等大檔案; 在使用者使用應用時,上述情況經常會出現,此時就要求應用具有儲存這些資料並在以後讀取的能力,也就是所謂的
Python實現矩陣相乘的三種方法
問題描述 分別實現矩陣相乘的3種演算法,比較三種演算法在矩陣大小分別為 22∗22 2^2*2^2, 23∗23 2^3*2^3, 24∗24 2^4*2^4, 25∗25 2^5*2^5,
實現HTTP伺服器的三種方法
1、使用socket簡單實現http協議: import java.io.*; import java.net.*; /** * MyHttpServer 實現一個簡單的HTTP伺服器端,可以獲取使用者提交的內容 * 並給使用者一個response * 因為
Java實現定時排程的三種方法
1、Timer Timer myTimer = new Timer(); myTimer.schedule(new Worker(), 1000);//1秒後執行 // 2012-02-28 09:58:00執行 myT
java實現定時任務的三種方法
/** * 普通thread * 這是最常見的,建立一個thread,然後讓它在while迴圈裡一直執行著, * 通過sleep方法來達到定時任務的效果。這樣可以快速簡單的實現,程式碼如下: * @author GT * */ public class Task
介面學習,實現多型的三種方法何時使用
介面是一種規範。 只要一個類繼承了一個介面,這個類就必須實現這個介面中所有的成員 為了多型。 介面不能被例項化。 也就是說,介面不能new(不能建立物件) 介面中的成員不能加“訪問修飾符”,介面中的成員訪問修飾符為public,不能修改。 (預設為publi
實現區域性重新整理的三種方法
1、 AJAX主要應用到的是區域性重新整理。也就是當頁面上的摸一個標籤內容需要重新整理,為了不引起整個頁面的回發,通常利用AJAX來解決。 2、獲取其他網頁的內容。當本頁內容基於其他網站時(例如天氣預報),通常也使用AJAX+正則表示式的方法,從外網截獲自己需要的內容。
C#實現字元替換的三種方法
最簡單粗暴的方法 C#封裝了Replace的方法,這個方法及其它的引數是這樣的。 string Replace(替換的目標,替換的字串) 返回值是替換後的字串 string str = "11xx1111x"; Console.Wri
jQuery實現圖片懶載入的兩種方法記錄
記錄一 整體思路: 設定個data-original(自定義一個屬性)來存放真實地址 當滾動頁面時,檢查所有的img標籤,看是否出現在視野中,如果已經出現在了視野中,那繼續再進行判斷,看其是否已經被載入過了,如果還沒有被載入過,那就進行載入。 程式碼: laz
C#實現發送郵件的三種方法
thumbnail catch plugins () listbox 幫助 哈希 .text sbo 本文實例講述了C#實現發送郵件的三種方法。分享給大家供大家參考。具體方法分析如下: 一、問題: 最近公司由於一個R&I;項目的需要,用戶要求在購買產品或出貨等
QComboBox實現復選功能(三種方法:嵌套QListWidget, 設置QStandardItemModel, 設置Delegate)
編輯 int() move bsp 下一個 tab url 進行 問題 今天介紹一下一個小東西 — 如何讓QComboBox實現復選功能? 需求: 下拉列表有復選功能 不可編輯 顯示所有選中項 關於QComboBox的復選功能有幾種