2013-03-16 113 views
10

我一直在使用CWAC's EndlessAdapter來實現無限滾動ListViews。ViewPager的無盡適配器

我想完成ViewPager的等價物。不幸的是,PageAdapter和ListAdapter不共享相同的基類。

這是什麼最好的方法呢?存在已經處理了這個問題的圖書館嗎?

+1

如果你已經實現,請分享你的解決方案在gitHub或任何你喜歡的地方:) – 2014-04-07 02:44:31

回答

14

什麼是最好的方式去做這件事?

將「無盡的」邏輯添加到您自己的PagerAdapter的實施中。或者,如果您願意,請嘗試創建一個裝飾PagerAdapter,這是EndlessAdapter修飾常規Adapter的方式。

後者可能會很棘手,因爲PagerAdapter設計爲頁面是視圖或片段,而像FragmentPagerAdapter這樣的類內部的片段處理有點嚇人。

是否存在已經處理了這個問題的庫?

沒有我知道的。

主要是因爲用例看起來並不那麼引人注目。使用ListView,用戶可以扔掉列表,快速滾動數十或數百行。因此,使用「我們到最後」作爲加載更多數據的觸發器似乎是合理的。然而,使用ViewPager時,通常需要更長的時間才能完成,特別是如果您未使用PagerTabStrip或同等效果。因此,等到用戶開始加載其他數據的過程結束時,用戶似乎會感到煩惱 - 您已經有時間去檢索更多數據,但沒有使用它。

因此,您可以選擇使用您的ViewPager註冊ViewPager.OnPageChangeListener。當onPageSelected(),你認爲自己接近尾聲,啓動AsyncTask(或其他)去收集更多的數據。然後就是你需要更新PagerAdapter使用的數據,並且在數據更新後在那個適配器上調用notifyDataSetChanged()

+0

當然有用例 - 尤其是當片段實際上不依賴於加載大量數據,但是例如viewpager的位置只是反映了你看到的數據的索引。例如:我想要一個ViewPager,每天都有一個頁面,從今天開始,如果你願意的話,可以向右延伸到 - 無窮大。翻頁僅僅意味着切換顯示的日期,並且顯示的數據只是計算出來的,而不是加載的。我仍然不知道如何實現這個... – Zordid 2014-02-21 10:20:53

+0

@ Zordid:正如我在我的回答中指出的,要創建一個「無限的」ViewPager,您必須在自定義的PagerAdapter實現中擁有該邏輯。 「FragmentPagerAdapter」和「FragmentStatePagerAdapter」都無法做到這一點,因爲您將耗盡內存,因爲它們會爲每個頁面創建新的片段。 – CommonsWare 2014-02-21 12:29:41

+0

目前我使用'FragmentStatePagerAdapter',到目前爲止我沒有達到極限。但我不確定這是因爲國家的保存 - 我的意見確實沒有一個國家,因爲每個頁面只反映了日曆中選定的一天...我想我應該用我的自定義適配器重寫 - 或只需切換到視圖而不是片段... – Zordid 2014-03-15 08:59:23

5

也許你可以「假吧」,如下所示:

你很可能顯示的頁面huuuuge數。使用FragmentStatePagerAdapter類: https://developer.android.com/reference/android/support/v13/app/FragmentStatePagerAdapter.html

通過返回Integer.MAX_VALUE落實getCount方法。
通過總是返回POSITION_NONE來實現getItemPosition方法。
如您所願執行getItem方法,返回相應的片段。

然後,當承載ViewPager的活動啓動時,將ViewPager的初始位置設置爲非常大的數字,例如, viewPager.setCurrentItem(Integer.MAX_VALUE/2);

我還沒有嘗試過這個...... YMMV! :)

6
@Override 
public int getCount() { 
    return (Integer.MAX_VALUE); 
    //artificially large value for infinite scrolling 
} 

public int getRealCount(){ 
//Do something to return the actual number of objects. 
} 


@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    int virtualPosition = position % getRealCount(); 
    return instantiateVirtualItem(container, virtualPosition); 
} 

public Object instantiateVirtualItem(ViewGroup container, final int position) {    
//Do the required part here 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    int virtualPosition = position % getRealCount(); 
    destroyVirtualItem(container, virtualPosition, object); 
} 


public void destroyVirtualItem(ViewGroup container, int position, Object object){ 
    container.removeView((View) object);    
} 

現在,最重要的部分

pager.setOffscreenPageLimit(10); //your choice 
pager.setCurrentItem(Integer.MAX_VALUE/2,false); 
//pager is the ViewPager object 

PS:我已經成功地實現了這個。詢問你是否仍然有疑問。

+0

我也使用這種模式,但我正在尋求更好的解決方案... – stefan 2014-12-10 16:45:23

+0

@stefan做這裏告訴你,當你找到一個。 – Shakti 2014-12-10 17:58:59

+1

猜測唯一的選擇是修改ViewPager。對於我的情況,一個可滑動的日曆,它也將是一個DateTime而不是一個整數的項目是很好的... – stefan 2014-12-10 22:50:44

相關問題