1. 程式人生 > >ViewPager系列之ViewPager無限迴圈滑動原理、程式碼、2種實現方法比較

ViewPager系列之ViewPager無限迴圈滑動原理、程式碼、2種實現方法比較

目前ViewPager實現無限迴圈有2種方法,直接上具體方法:

方法1:重寫 PagerAdapter 中的 getCount() 方法。其實只是在計算item 數目的時候給了一個很大的數,然後通過呼叫setCurrentItem(position)方法,相當於把起始位置放到了中間的某個位置而已。這裡在重寫instantiateItem()方法的時候,記得角標的大小,這裡就就不上具體程式碼了。

@Override
public int getCount() {
    return Integer.MAX_VALUE;
}

方法2:重寫了 OnPageChangeListener 介面中的onPageSelected 方法。

先上一下效果圖,大家一定要留意git圖的頁面切換效果。

ViewPager無限迴圈

gif圖效果看的不明顯,其實這裡是有瑕疵的。在迴圈的第一張和最後一張會有點不太協調(我這裡是藍色海洋和 路飛艾斯這兩張圖片的切換),之前錄了個清晰的git可以清楚的看到這一點,但是因為圖片上傳不能超過2M,修改gif後看得不明顯了,具體的還是自己嘗試下才清楚。

ViewPager無限迴圈原理分析:

ViewPager真實無限迴圈

如果舊資料是的結構是 List 1,2,3。 那麼拼接的新資料格式為List 3,1,2,3,1。

初始化我們讓ViewPager指向position=1這個位置,也就是List<舊資料的第一條資料>。如果向左滑動,那麼當前顯示的List<0>這個頁面,也就是List<新資料的第一條資料>,這會兒我們讓ViewPager重新指向紅色3的位置,也就是List<新資料長度-2>。這樣ViewPager就可以向左向右進行滑動了。

如果當前位置是在紅色3的頁面,也就是List<舊資料最後一條>資料對應的頁面。如果向右滑動,那麼當前顯示的List<新資料長度-1>這個也頁面,當滑動到這個頁面時會重新setCurrentItem 指定到第一條資料。

ViewPager無限迴圈Demo程式碼

xml 佈局

    <android.support.v4.view.ViewPager
         android:id="@+id/viewPager"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
> </android.support.v4.view.ViewPager>

Activity 程式碼

        // 留意這裡的順序。
        list2.add(R.drawable.image_08);
        list2.add(R.drawable.image_06);
        list2.add(R.drawable.image_07);
        list2.add(R.drawable.image_08);
        list2.add(R.drawable.image_06);

        mVviewPager = (ViewPager) findViewById(R.id.viewPager);
        // 這裡的MultiplePagerAdapter2不用管,我直接用的其他的adapter.具體的看需求了。
        MultiplePagerAdapter2 adapter2 = new MultiplePagerAdapter2(this, list2);
        mVviewPager.setAdapter(adapter2);
        // 初始化指定位置
        mVviewPager.setCurrentItem(1);
        // 重點看下面的程式碼
        mVviewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            int currentPosition;

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                currentPosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // ViewPager.SCROLL_STATE_IDLE 標識的狀態是當前頁面完全展現,並且沒有動畫正在進行中,如果不
                // 是此狀態下執行 setCurrentItem 方法回在首位替換的時候會出現跳動!
                if (state != ViewPager.SCROLL_STATE_IDLE) return;

                // 當檢視在第一個時,將頁面號設定為圖片的最後一張。
                if (currentPosition == 0) {
                    mVviewPager.setCurrentItem(list2.size() - 2, false);

                } else if (currentPosition == list2.size() - 1) {
                    // 當檢視在最後一個是,將頁面號設定為圖片的第一張。
                    mVviewPager.setCurrentItem(1, false);
                }
            }
        });

ViewPager無限迴圈兩種方法比較:

流暢性:第一種方法 顯然要比第二種方法要流暢很多。

應用場景: 如果只是讓使用者自行滑動跳轉pager 的話,我比較推薦第一種。畢竟流暢性要好很多。如果是定時無限迴圈的話,可以嘗試用第二種方法。當然具體在pager轉場動畫裡是直接跳轉還是有個過渡動畫來緩衝一下,看具體的專案中更適合哪種了。

介紹下 setCurrentItem (int item, boolean smoothScroll) 和 setCurrentItem (int item) 的區別。

其實谷歌文件已經介紹的很詳細了。

public void setCurrentItem (int item, boolean smoothScroll)
Set the currently selected page. // 設定當前選擇的頁面
引數
item int: Item index to select
smoothScroll boolean: True to smoothly scroll to the new item, false to transition immediately
// 如果smoothScroll 為true,則平滑滾動到指定頁面,false 則直接跳轉到指定頁面

public void setCurrentItem (int item)
Set the currently selected page. If the ViewPager has already been through its first layout with its current adapter there will be a smooth animated transition between the current item and the specified item.
// 設定當前選擇的頁面。如果ViewPager 已經通過指定頁面,那麼將會在當前iten 與指定item 有一個平滑的過渡動畫。
引數
item int: Item index to select