無限迴圈的ViewPager--LoopViewPager
需求
無限迴圈的ViewPager在Android開發中經常遇到,例如Banner,滾屏廣告等等,下面介紹一個我做的無限迴圈ViewPager
效果圖

LoopViewPager操作效果.gif
思路
基本思路跟大多數先驅的做法差不多。
- 將PagerAdapter的getCount方法返回值為一個較大的數字,這裡我返回了int型別的最大值,即Integer.MAX_VALUE;
- 初始item設定為Integer.MAX_VALUE的一半,即Integer.MAX_VALUE / 2;
- PagerAdapter的instantiateItem執行時根據position和資料列表計算出當前position應當顯示的資料;
- 每一個Item的資料和View都繫結在ViewHolder的實體內;
- 封裝一個ViewHolderCreator,ViewHolder的回收、獲取和更新都由ViewHolderCreator控制。
關於ViewHolderCreator

LoopViewPager工作流程.png
上圖所示
當setOffscreenPageLimit方法設定limit為2,即左右預載入數各為2,從ViewHolderCreator中獲取5個空閒的ViewHolder,載入初始資料。當向右翻一頁時,回收最左邊的ViewHolder,放入空閒的ViewHolder佇列中,獲取一個空閒的ViewHolder放入右邊,填充資料。
使用方法
在XML中配置或者直接new一個都可以
<com.riverlet.riverletviewpager.LoopViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="300dp" />
LoopViewPager viewpager = view.findViewById(R.id.viewpager);
或者
LoopViewPager viewpager = new LoopViewPager(getContext());
給LoopViewPager設定資料和ViewHolderCreator
viewpager.setData(dataList, new LoopViewPager.ViewHolderCreator() { @Override public LoopViewPager.ViewHolder create() { TextView textView = new TextView(getContext()); textView.setBackgroundColor(0xff43CD80); textView.setTextColor(Color.WHITE); textView.setTextSize(50); textView.setGravity(Gravity.CENTER); textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return new LoopViewHolder(textView); } });
方法介紹
/** * 設定基礎資料和ViewHolderCreator * * @param dataList 資料列表 * @param viewHolderCreator */ public void setData(List dataList, @NonNull ViewHolderCreator viewHolderCreator) ; /** * 獲取當前顯示Item的ViewHolder,即可獲取當前顯示的資料和View * * @return */ public ViewHolder getCurrentItemViewHolder(); /** * 根據Item位置獲取它的ViewHolder * * @param position * @return */ public ViewHolder getViewHolderOfPosition(int position); /** * 跳轉到指定Data的位置 * * @param data */ public void setCurrentItemOfData(Object data); /** * 跳轉到指定Data的位置 * * @param data * @param smoothScroll 是否帶滾動動畫 */ public void setCurrentItemOfData(Object data, boolean smoothScroll); /** * 翻到下一頁 */ public void nextPage(); /** * 翻到上一頁 */ public void lastPage(); /** * 設定當前頁變化的監聽 * @param onCurrentPageChangeListener */ public void setOnCurrentPageChangeListener(OnCurrentPageChangeListener onCurrentPageChangeListener);
注意
- 無限迴圈不是真的無限迴圈,總頁數為Integer.MAX_VALUE,即2147483647,比較大,初始設定在中間位置;
- 雖然總頁數為2147483647,但實際載入的頁數只有5個(當前顯示頁以及左右個兩個);
- 因為實際載入頁數只有5個,所以setCurrentItem跳轉到其他未載入的頁數時,會出現bug,
所以在LoopViewPager裡面setCurrentItem被阻斷了,封裝了setCurrentItemOfData作為跳轉方法。
原始碼及Demo安裝包
原始碼: ofollow,noindex">ViewPagerDemo
Demo安裝包: app-debug.apk
引申
無限新增的ViewPager:InfiniteViewPager