pagertab 自定義控件碎片滑動

package com.itcast.googleplayteach.ui.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.EdgeEffectCompat;
import android.support.v4.widget.ScrollerCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.ImageButton;
import android.widget.TextView;

import com.itcast.googleplayteach.R;
import com.itcast.googleplayteach.ui.activity.BaseActivity;
import com.itcast.googleplayteach.utils.UIUtils;

public class PagerTab extends ViewGroup {

    private ViewPager mViewPager;
    private PageListener mPageListener = new PageListener();// 用於註冊給ViewPager監聽狀態和滾動
    private OnPageChangeListener mDelegatePageListener;// 用於通知外界ViewPager的狀態和滾動
    private BaseActivity mActivity;

    private int mDividerPadding = 12;// 分割線上下的padding
    private int mDividerWidth = 1;// 分割線的寬度
    private int mDividerColor = 0x1A000000;// 分割線顏色
    private Paint mDividerPaint;// 分割線的畫筆

    private int mIndicatorHeight = 4;// 指示器的高度
    private int mIndicatorWidth;// 指示器的寬度,是動態的隨着tab的寬度變化
    private int mIndicatorLeft;// 指示器的距離左邊的距離
    private int mIndicatorColor = 0xFF0084FF;// 指示器顏色
    private Paint mIndicatorPaint; // 指示器的畫筆

    private int mContentWidth;// 記錄自身內容的寬度
    private int mContentHeight;// 記錄自身內容的高度

    private int mTabPadding = 24;// tab左右的內邊距
    private int mTabTextSize = 16; // tab文字大小
    private int mTabBackgroundResId = R.drawable.bg_tab_text;// tab背景資源
    private int mTabTextColorResId = R.color.tab_text_color; // tab文字顏色
    private int mTabCount;// tab的個數

    private int mCurrentPosition = 0;// 當前光標所處的tab,規則是以光標的最左端所在的item的position
    private float mCurrentOffsetPixels;// 光標左邊距離當前光標所處的tab的左邊距離
    private int mSelectedPosition = 0; // 當前被選中的tab,用於記錄手指點擊tab的position

    private boolean mIsBeingDragged = false;// 是否處於拖動中
    private float mLastMotionX;// 上一次手指觸摸的x座標
    private VelocityTracker mVelocityTracker;// 用於記錄速度的幫助類
    private int mMinimumVelocity;// 系統默認的最小滿足fling的速度
    private int mMaximumVelocity;// 系統默認最大的fling速度
    private int mTouchSlop;// 系統默認滿足滑動的最小位移

    private ScrollerCompat mScroller;// 處理滾動的幫助者
    private int mLastScrollX;// 記錄上一次滾動的x位置,這是用於處理overScroll,實際位置可能會受到限制

    private int mMaxScrollX = 0;// 控件最大可滾動的距離
    private int mSplitScrollX = 0;// 根據item的個數,計算出每移動一個item控件需要移動的距離

    private EdgeEffectCompat mLeftEdge;// 處理overScroll的反饋效果
    private EdgeEffectCompat mRightEdge;

    public PagerTab(Context context) {
        this(context, null);
    }

    public PagerTab(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PagerTab(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (context instanceof BaseActivity) {
            mActivity = (BaseActivity) context;
        }
        init();
        initPaint();
    }

    /** 初始化一些常量 */
    private void init() {
        // 把一個值從dip轉換成px
        mIndicatorHeight = UIUtils.dip2px(mIndicatorHeight);
        mDividerPadding = UIUtils.dip2px(mDividerPadding);
        mTabPadding = UIUtils.dip2px(mTabPadding);
        mDividerWidth = UIUtils.dip2px(mDividerWidth);
        mTabTextSize = UIUtils.dip2px(mTabTextSize);
        // 創建一個scroller
        mScroller = ScrollerCompat.create(mActivity);
        // 獲取一個系統關於View的常量配置類
        final ViewConfiguration configuration = ViewConfiguration
                .get(mActivity);
        // 獲取滑動的最小距離
        mTouchSlop = configuration.getScaledTouchSlop();
        // 獲取fling的最小速度
        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
        // 獲取fling的最大速度
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();

        mLeftEdge = new EdgeEffectCompat(mActivity);
        mRightEdge = new EdgeEffectCompat(mActivity);
    }

    /** 初始化筆 */
    private void initPaint() {
        mIndicatorPaint = new Paint();
        mIndicatorPaint.setAntiAlias(true);
        mIndicatorPaint.setStyle(Paint.Style.FILL);
        mIndicatorPaint.setColor(mIndicatorColor);

        mDividerPaint = new Paint();
        mDividerPaint.setAntiAlias(true);
        mDividerPaint.setStrokeWidth(mDividerWidth);
        mDividerPaint.setColor(mDividerColor);
    }

    /** 設置ViewPager */
    public void setViewPager(ViewPager viewPager) {
        if (viewPager == null || viewPager.getAdapter() == null) {
            throw new IllegalStateException(
                    "ViewPager is null or ViewPager does not have adapter instance.");
        }
        mViewPager = viewPager;
        onViewPagerChanged();
    }

    private void onViewPagerChanged() {
        mViewPager.setOnPageChangeListener(mPageListener);// 給ViewPager設置監聽
        mTabCount = mViewPager.getAdapter().getCount();// 有多少個tab需要看ViewPager有多少個頁面
        for (int i = 0; i < mTabCount; i++) {
            if (mViewPager.getAdapter() instanceof IconTabProvider) {// 如果想要使用icon作爲tab,則需要adapter實現IconTabProvider接口
                addIconTab(i,
                        ((IconTabProvider) mViewPager.getAdapter())
                                .getPageIconResId(i));
            } else {
                addTextTab(i, mViewPager.getAdapter().getPageTitle(i)
                        .toString());
            }
        }
        ViewTreeObserver viewTreeObserver = getViewTreeObserver();
        if (viewTreeObserver != null) {// 監聽第一個的全局layout事件,來設置當前的mCurrentPosition,顯示對應的tab
            viewTreeObserver
                    .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            getViewTreeObserver().removeGlobalOnLayoutListener(
                                    this);// 只需要監聽一次,之後通過listener回調即可
                            mCurrentPosition = mViewPager.getCurrentItem();
                            if (mDelegatePageListener != null) {
                                mDelegatePageListener
                                        .onPageSelected(mCurrentPosition);
                            }
                        }
                    });
        }
    }

    /** 設置監聽,因爲Tab會監聽ViewPager的狀態,所以不要給ViewPager設置監聽了,設置給Tab,由Tab轉發 */
    public void setOnPageChangeListener(OnPageChangeListener listener) {
        mDelegatePageListener = listener;
    }

    /** 添加文字tab */
    private void addTextTab(final int position, String title) {
        TextView tab = new TextView(mActivity);
        tab.setText(title);
        tab.setGravity(Gravity.CENTER);
        tab.setSingleLine();
        tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTabTextSize);
        tab.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        tab.setTextColor(UIUtils.getColorStateList(mTabTextColorResId));
        tab.setBackgroundDrawable(UIUtils.getDrawable(mTabBackgroundResId));
        tab.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT));
        addTab(position, tab);
    }

    /** 添加圖片icon */
    private void addIconTab(final int position, int resId) {
        ImageButton tab = new ImageButton(mActivity);
        tab.setImageResource(resId);
        tab.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT));
        addTab(position, tab);
    }

    private void addTab(final int position, View tab) {
        tab.setFocusable(true);
        // 設置tab的點擊事件,當tab被點擊時候切換pager的頁面
        tab.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mViewPager.setCurrentItem(position);
            }
        });
        tab.setPadding(mTabPadding, 0, mTabPadding, 0);
        addView(tab, position);
    }

    /** 測量時的回調 */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 獲取控件自身的寬高,模式
        int widthSize = MeasureSpec.getSize(widthMeasureSpec)
                - getPaddingLeft() - getPaddingRight();
        int heightSize = MeasureSpec.getSize(heightMeasureSpec)
                - getPaddingBottom() - getPaddingBottom();
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int totalWidth = 0;
        int highest = 0;
        int goneChildCount = 0;
        for (int i = 0; i < mTabCount; i++) {
            final View child = getChildAt(i);
            if (child == null || child.getVisibility() == View.GONE) {
                goneChildCount--;
                continue;
            }
            int childWidthMeasureSpec;
            int childHeightMeasureSpec;

            LayoutParams childLayoutParams = child.getLayoutParams();
            if (childLayoutParams == null) {
                childLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                        LayoutParams.WRAP_CONTENT);
            }

            if (childLayoutParams.width == LayoutParams.MATCH_PARENT) {
                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize,
                        MeasureSpec.EXACTLY);
            } else if (childLayoutParams.width == LayoutParams.WRAP_CONTENT) {
                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize,
                        MeasureSpec.AT_MOST);
            } else {
                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
                        childLayoutParams.width, MeasureSpec.EXACTLY);
            }

            if (childLayoutParams.height == LayoutParams.MATCH_PARENT) {
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        heightSize, MeasureSpec.EXACTLY);
            } else if (childLayoutParams.height == LayoutParams.WRAP_CONTENT) {
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        heightSize, MeasureSpec.AT_MOST);
            } else {
                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        childLayoutParams.height, MeasureSpec.EXACTLY);
            }

            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();

            totalWidth += childWidth;
            highest = highest < childHeight ? childHeight : highest;
        }

        if (totalWidth <= widthSize) {// 如果子Tab的總寬度小於PagerTab,則採用平分模式
            int splitWidth = (int) (widthSize
                    / (mTabCount - goneChildCount + 0.0f) + 0.5f);
            for (int i = 0; i < mTabCount; i++) {
                final View child = getChildAt(i);
                if (child == null || child.getVisibility() == View.GONE) {
                    continue;
                }
                int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
                        splitWidth, MeasureSpec.EXACTLY);
                int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        child.getMeasuredHeight(), MeasureSpec.EXACTLY);
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }
            mMaxScrollX = 0;
            mSplitScrollX = 0;
        } else {// 如果所有子View大於控件的寬度
            mMaxScrollX = totalWidth - widthSize;
            mSplitScrollX = (int) (mMaxScrollX
                    / (mTabCount - goneChildCount - 1.0f) + 0.5f);
        }

        if (widthMode == MeasureSpec.EXACTLY) {
            mContentWidth = widthSize;
        } else {
            mContentWidth = totalWidth;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            mContentHeight = heightSize;
        } else {
            mContentHeight = highest;
        }

        int measureWidth = mContentWidth + getPaddingLeft() + getPaddingRight();
        int measureHeight = mContentHeight + getPaddingTop()
                + getPaddingBottom();
        setMeasuredDimension(measureWidth, measureHeight);
    }

    /** 佈局時的回調 */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {// 這裏簡化了,沒有考慮margin的情況
        if (changed) {
            int height = b - t;// 控件供子View顯示的高度
            int left = l;
            for (int i = 0; i < mTabCount; i++) {
                final View child = getChildAt(i);
                if (child == null || child.getVisibility() == View.GONE) {
                    continue;
                }
                int top = (int) ((height - child.getMeasuredHeight()) / 2.0f + 0.5f);// 如果控件比tab要高,則居中顯示
                int right = left + child.getMeasuredWidth();
                child.layout(left, top, right, top + child.getMeasuredHeight());// 擺放tab
                left = right;// 因爲是水平擺放的,所以爲下一個準備left值
            }
        }
    }

    /** 繪製時的回調 */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        final int height = getHeight();
        // 畫指示器
        canvas.drawRect(mIndicatorLeft, height - mIndicatorHeight,
                mIndicatorLeft + mIndicatorWidth, height, mIndicatorPaint);

        // 畫分割線
        for (int i = 0; i < mTabCount - 1; i++) {// 分割線的個數比tab的個數少一個
            final View child = getChildAt(i);
            if (child == null || child.getVisibility() == View.GONE) {
                continue;
            }
            if (child != null) {
                canvas.drawLine(child.getRight(), mDividerPadding,
                        child.getRight(), mContentHeight - mDividerPadding,
                        mDividerPaint);
            }
        }
        // 因爲overScroll效果是一個持續效果,所以需要持續畫
        boolean needsInvalidate = false;
        if (!mLeftEdge.isFinished()) {// 如果效果沒停止
            final int restoreCount = canvas.save();// 先保存當前畫布
            final int heightEdge = getHeight() - getPaddingTop()
                    - getPaddingBottom();
            final int widthEdge = getWidth();
            canvas.rotate(270);
            canvas.translate(-heightEdge + getPaddingTop(), 0);
            mLeftEdge.setSize(heightEdge, widthEdge);
            needsInvalidate |= mLeftEdge.draw(canvas);
            canvas.restoreToCount(restoreCount);
        }
        if (!mRightEdge.isFinished()) {
            final int restoreCount = canvas.save();
            final int widthEdge = getWidth();
            final int heightEdge = getHeight() - getPaddingTop()
                    - getPaddingBottom();
            canvas.rotate(90);
            canvas.translate(-getPaddingTop(), -(widthEdge + mMaxScrollX));
            mRightEdge.setSize(heightEdge, widthEdge);
            needsInvalidate |= mRightEdge.draw(canvas);
            canvas.restoreToCount(restoreCount);
        }
        if (needsInvalidate) {
            postInvalidate();
        }
    }

    /** 觸摸事件是否攔截的方法 */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        if (mIsBeingDragged && action == MotionEvent.ACTION_MOVE) {// 當已經處於拖動,並且當前事件是MOVE,直接消費掉
            return true;
        }
        switch (action) {
        case MotionEvent.ACTION_DOWN: {
            final float x = ev.getX();
            mLastMotionX = x; // 記錄住當前的x座標
            mIsBeingDragged = !mScroller.isFinished();// 如果按下的時候還在滾動,則把狀態處於拖動狀態
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            final float x = ev.getX();
            final int xDiff = (int) Math.abs(x - mLastMotionX);// 計算兩次的差值
            if (xDiff > mTouchSlop) {// 如果大於最小移動的距離,則把狀態改變爲拖動狀態
                mIsBeingDragged = true;
                mLastMotionX = x;
                ViewParent parent = getParent();// 並請求父View不要再攔截自己觸摸事件,交給自己處理
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                }
            }
            break;
        }
        case MotionEvent.ACTION_CANCEL:// 當手指離開或者觸摸事件取消的時候,把拖動狀態取消掉
        case MotionEvent.ACTION_UP:
            mIsBeingDragged = false;
            break;
        }
        return mIsBeingDragged;// 如果是拖動狀態,則攔截事件,交給自己的onTouch處理
    }

    /** 觸摸事件的處理方法 */
    public boolean onTouchEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);
        final int action = ev.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN: {// 如果是down事件,記錄住當前的x座標
            final float x = ev.getX();
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
            }
            mLastMotionX = x;
            break;
        }
        case MotionEvent.ACTION_MOVE: {
            final float x = ev.getX();
            final float deltaX = x - mLastMotionX;
            if (!mIsBeingDragged) {// 如果還沒有處於拖動,則判斷兩次的差值是否大於最小拖動的距離
                if (Math.abs(deltaX) > mTouchSlop) {
                    mIsBeingDragged = true;
                }
            }
            if (mIsBeingDragged) {// 如果處於拖動狀態,記錄住x座標
                mLastMotionX = x;
                onMove(deltaX);
            }
            break;
        }
        case MotionEvent.ACTION_UP: {
            if (mIsBeingDragged) {
                final VelocityTracker velocityTracker = mVelocityTracker;
                // 先對速度進行一個調整,第一個參數是時間單位,1000毫秒,第二個參數是最大速度。
                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
                float velocity = velocityTracker.getXVelocity();// 獲取水平方向上的速度
                onUp(velocity);
            }
        }
        case MotionEvent.ACTION_CANCEL: {
            mIsBeingDragged = false;
            if (mVelocityTracker != null) {
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            }
            break;
        }
        }
        return true;
    }

    private void onMove(float x) {
        if (mMaxScrollX <= 0) {
            if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
                mViewPager.fakeDragBy(x);
            }
        } else {
            int scrollByX = -(int) (x + 0.5);
            if (getScrollX() + scrollByX < 0) {
                scrollByX = 0 - getScrollX();
                mLeftEdge.onPull(Math.abs(x) / getWidth());
            }
            if (getScrollX() + scrollByX > mMaxScrollX) {
                scrollByX = mMaxScrollX - getScrollX();
                mRightEdge.onPull(Math.abs(x) / getWidth());
            }
            scrollBy(scrollByX, 0);
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    private void onUp(float velocity) {
        if (mMaxScrollX <= 0) {
            if (mViewPager.isFakeDragging())
                mViewPager.endFakeDrag();
        } else {
            if (Math.abs(velocity) <= mMinimumVelocity) {
                return;
            }
            mScroller.fling(getScrollX(), 0, -(int) (velocity + 0.5), 0, 0,
                    mMaxScrollX, 0, 0, 270, 0);
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            int oldX = mLastScrollX;
            mLastScrollX = mScroller.getCurrX();
            if (mLastScrollX < 0 && oldX >= 0) {
                mLeftEdge.onAbsorb((int) mScroller.getCurrVelocity());
            } else if (mLastScrollX > mMaxScrollX && oldX <= mMaxScrollX) {
                mRightEdge.onAbsorb((int) mScroller.getCurrVelocity());
            }
            int x = mLastScrollX;
            if (mLastScrollX < 0) {
                x = 0;
            } else if (mLastScrollX > mMaxScrollX) {
                x = mMaxScrollX;
            }
            scrollTo(x, 0);
        }
        ViewCompat.postInvalidateOnAnimation(this);
    }

    /** 檢測mIndicatorOffset的合法性,並計算出其他有關tab的屬性值 */
    private void checkAndcalculate() {
        // 如果指示器起始位置比第一個tab的起始位置還要小,糾正爲第一個tab的起始位置,指示器寬度就是第一個tab的寬度
        final View firstTab = getChildAt(0);
        if (mIndicatorLeft < firstTab.getLeft()) {
            mIndicatorLeft = firstTab.getLeft();
            mIndicatorWidth = firstTab.getWidth();
        }
        // 如果指示器起始位置比最後一個tab的起始位置還要大,糾正爲最後一個tab的起始位置,指示器寬度就是最後一個tab的寬度
        View lastTab = getChildAt(mTabCount - 1);
        if (mIndicatorLeft > lastTab.getLeft()) {
            mIndicatorLeft = lastTab.getLeft();
            mIndicatorWidth = lastTab.getWidth();
        }
        // 通過指示器的起始位置計算出當前處於第幾個position,並且計算出已經偏移了多少,偏移量是以當前所處的tab的寬度的百分比
        for (int i = 0; i < mTabCount; i++) {
            View tab = getChildAt(i);
            if (mIndicatorLeft < tab.getLeft()) {
                mCurrentPosition = i - 1;
                View currentTab = getChildAt(mCurrentPosition);
                mCurrentOffsetPixels = (mIndicatorLeft - currentTab.getLeft())
                        / (currentTab.getWidth() + 0.0f);
                break;
            }
        }
    }

    /** 滾動到指定的child */
    public void scrollSelf(int position, float offset) {
        if (position >= mTabCount) {
            return;
        }
        final View tab = getChildAt(position);
        mIndicatorLeft = (int) (tab.getLeft() + tab.getWidth() * offset + 0.5);
        int rightPosition = position + 1;
        if (offset > 0 && rightPosition < mTabCount) {
            View rightTab = getChildAt(rightPosition);
            mIndicatorWidth = (int) (tab.getWidth() * (1 - offset)
                    + rightTab.getWidth() * offset + 0.5);
        } else {
            mIndicatorWidth = tab.getWidth();
        }
        checkAndcalculate();

        int newScrollX = position * mSplitScrollX
                + (int) (offset * mSplitScrollX + 0.5);
        if (newScrollX < 0) {
            newScrollX = 0;
        }
        if (newScrollX > mMaxScrollX) {
            newScrollX = mMaxScrollX;
        }
        // scrollTo(newScrollX, 0);//滑動
        int duration = 100;
        if (mSelectedPosition != -1) {
            duration = (Math.abs(mSelectedPosition - position)) * 100;
        }
        mScroller.startScroll(getScrollX(), 0, (newScrollX - getScrollX()), 0,
                duration);
        ViewCompat.postInvalidateOnAnimation(this);
    }

    /** 選中指定位置的Tab */
    private void selectTab(int position) {
        for (int i = 0; i < mTabCount; i++) {
            View tab = getChildAt(i);
            if (tab != null) {
                tab.setSelected(position == i);
            }
        }
    }

    /**
     * ViewPager的OnPageChangeListener實現類,因爲我們需要在PagerTab中獲取PagerView的監聽,
     * 以便可以調整tab
     */
    private class PageListener implements OnPageChangeListener {
        @Override
        public void onPageScrolled(int position, float positionOffset,
                final int positionOffsetPixels) {
            // 根據VierPager的偏移值來滾動tab
            scrollSelf(position, positionOffset);
            if (mDelegatePageListener != null) {// 這個是提供給外部的
                mDelegatePageListener.onPageScrolled(position, positionOffset,
                        positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                mSelectedPosition = -1;
            }
            if (mDelegatePageListener != null) {
                mDelegatePageListener.onPageScrollStateChanged(state);
            }
        }

        @Override
        public void onPageSelected(int position) {
            System.out.println("onPageSelected:" + position);
            mSelectedPosition = position;
            selectTab(position);
            if (mDelegatePageListener != null) {
                mDelegatePageListener.onPageSelected(position);
            }
        }
    }

    /** 如果指示器希望是圖片,則繼承該接口 */
    public interface IconTabProvider {
        public int getPageIconResId(int position);

        public int getPageSelectedIconResId();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章