自定义PagerTab

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载,违者必究。 https://blog.csdn.net/Cricket_7/article/details/89002885

1,实现效果

2,实现逻辑

【1】创建自定义控件

  • 类copy到自己要用的项目内

  • 资源文件的修改

bg_tab_text.xml  tab背景资源

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable ="@color/colorPrimary"/>

    <item android:state_checked="true" android:drawable ="@color/colorPrimary"/>

    <item android:drawable="@android:color/transparent"/>

</selector>

rating_bar_bg.xml

<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <!---->

    <item android:id="@android:id/background" android:drawable="@mipmap/rating_small_empty"/>

    <item android:id="@android:id/secondaryProgress" android:drawable="@mipmap/rating_small_half"/>

    <item android:id="@android:id/progress" android:drawable="@mipmap/rating_small_full"/>

</layer-list>

selector_list_item_bg.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable="@drawable/list_item_bg_pressed"/>

    <item android:drawable="@drawable/list_item_bg_normal"/>

</selector>

tab_text_color.xml   tab文字颜色

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:color="@color/tab_text_color_selected"/>

    <item android:color="@color/tab_text_color_normal"/>

</selector>

colors.xml选中和未选中的颜色

  <!--选中文字的颜色 蓝色-->

    <color name="tab_text_color_selected">#3F51B5</color>

    <!--未选中文字的颜色 黑色-->

    <color name="tab_text_color_normal">#000000</color>

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;

public class PagerTab extends ViewGroup {

    private ViewPager mViewPager;

    private PageListener mPageListener = new PageListener();//用于注册给ViewPager监听状�?和滚�?

    private OnPageChangeListener mDelegatePageListener;//用于通知外界ViewPager的状态和滚动

    private BaseActivity mActivity;//工程中所有的activity都需要去继承至BaseActivity,BaseActivity继承者Actvity

    private int mDividerPadding = 12;// 分割线上下的padding

    private int mDividerWidth = 1;// 分割线的宽度

    private int mDividerColor = 0x1A000000;//分割线颜�?

    private Paint mDividerPaint;//分割线的画笔

    private int mIndicatorHeight = 4;//指示器的高度

    private int mIndicatorWidth;//指示器的宽度,是动�?的随�?ab的宽度变�?

    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));

        //获取对应的一个颜色选择器,xml

        //根据颜色选择器的id,返回一个颜色选择器的对象

        tab.setTextColor(UIUtils.getColorStateList(mTabTextColorResId));

        tab.setBackgroundDrawable(UIUtils.getDrawable(mTabBackgroundResId));

        tab.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));

        /*

         * ben

         */

        if(position == 0){                                                  

            tab.setTextColor(getContext().getResources().getColor(R.color.tab_text_color_selected));

        }

        /*

         * ben

         */

        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) {

                //BEN

                if(position !=0){

                    View firstTab = getChildAt(0);

                    ((TextView)firstTab).setTextColor(getContext().getResources().getColor(R.color.tab_text_color_normal));

                }else{

                    View firstTab = getChildAt(0);

                    ((TextView)firstTab).setTextColor(getContext().getResources().getColor(R.color.tab_text_color_selected));

                }

                //BEN

                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();

    }

}

3,使用方法

pagerTab  和   viewpager一起使用

   pagertab.setViewPager(vpContent);

viewpager必须设置getPageTitle 方法,不配置会报空指针

//给指针自定义控件添加标题

        @Override

        public CharSequence getPageTitle(int position) {

            return stringArray[position];

        }

猜你喜欢

转载自blog.csdn.net/Cricket_7/article/details/89002885