1. 程式人生 > >為ViewPager新增頁面指示器效果(小圓點指示器)

為ViewPager新增頁面指示器效果(小圓點指示器)

· 背景

我們的應用幾乎都有啟動引導頁介紹,通常是3~4張引導圖,然後進入我們的主介面。大家可以發現,我們大部分引導介面都會有一種指示器(也就是小圓點,這裡比較常見)。除了引導頁以外呢,我們常見的廣告頁也經常會有這種指示器效果。

· 效果圖

實現這種效果的方式有多種多樣,雖然說很簡單,但是我們可以寫成一個通用的指示器類,在需要用到的地方例項化就可以了。這樣就會減少程式碼的重複。

· 實現思路及程式碼

    我們知道ViewPager有一個addOnPageChangeListener介面,這個介面可以對ViewPager的頁面改變進行監聽。那麼,這樣我們就可以通過這個介面監聽Page的Position,Page的Position位置無非就是對當前頁的指示器(小圓點)的狀態進行改變來迎合ViewPager,從而達到我們想要的效果。

我們看下程式碼:

public class PageIndicator implements ViewPager.OnPageChangeListener {
    private int mPageCount;//頁數
    private List<ImageView> mImgList;//儲存img總個數
    private int img_select;
    private int img_unSelect;

    public PageIndicator(Context context, LinearLayout linearLayout, int pageCount) {
        this.mPageCount = pageCount;

        mImgList = new ArrayList<>();
        img_select = R.drawable.dot_select;
        img_unSelect = R.drawable.dot_unselect;
        final int imgSize = 25;

        for (int i = 0; i < mPageCount; i++) {
            ImageView imageView = new ImageView(context);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            //為小圓點左右新增間距
            params.leftMargin = 10;
            params.rightMargin = 10;
            //給小圓點一個預設大小
            params.height = imgSize;
            params.width = imgSize;
            if (i == 0) {
                imageView.setBackgroundResource(img_select);
            } else {
                imageView.setBackgroundResource(img_unSelect);
            }
            //為LinearLayout新增ImageView
            linearLayout.addView(imageView, params);
            mImgList.add(imageView);
        }
    }

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

    @Override
    public void onPageSelected(int position) {
        for (int i = 0; i < mPageCount; i++) {
            //選中的頁面改變小圓點為選中狀態,反之為未選中
            if ((position % mPageCount) == i) {
                (mImgList.get(i)).setBackgroundResource(img_select);
            } else {
                (mImgList.get(i)).setBackgroundResource(img_unSelect);
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {}
}

我們分析一下上部分程式碼:

    這個類實現了OnPageChangeListener這個介面,這接口裡的方法我們就不一一講了,主要我們是在onPageSelected()這個方法內進行對小圓點的狀態進行改變的。我們例項化了一個LinerLayout容器用作存放小圓點,因為我們首次進入頁面,ViewPager預設postition是為0,在此我們得設定一個初始小圓點的狀態,也就是指向第一頁。我們在onPageSelected()方法中,改變當前頁面的小圓點狀態。

· ViewPager佈局檔案

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

        <LinearLayout
            android:id="@+id/dot_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginBottom="32dp"
            android:gravity="center"
            android:orientation="horizontal" />
    </FrameLayout>
</android.support.constraint.ConstraintLayout>

    這裡說明一下,小圓點可以選擇任意的圖片資源,而我是寫了一個drawable檔案,樣式比較簡單,也放出程式碼吧:

//選中
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <corners android:radius="1000dp" />
</shape>
//未選中
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#323232" />
    <corners android:radius="1000dp" />
</shape>

· 使用方法

    介面卡之類的程式碼我就不貼出來了,比較簡單。這樣便實現瞭如上圖的指示器效果了。

    我們這樣引用到我們的ViewPager上:

/**
* 第二個引數:存放小圓點的容器
* 第三個引數:ViewPager的頁面數量
*/
mViewPager.addOnPageChangeListener(new PageIndicator(getContext(), dotHorizontal, 3));