• viewpager标签栏之PagerTab


    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.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.shiwen.oil.R;
    import com.shiwen.oil.base.BaseActivity;
    import com.shiwen.oil.util.UiUtil;
    
    
    public class PagerTab extends ViewGroup {
    
        private ViewPager mViewPager;
        private PageListener mPageListener = new PageListener();//用于注册给ViewPager监听状态和滚动
        private ViewPager.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 = 0xFF2484E8;//指示器颜色
        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, -1);
        }
    
        public PagerTab(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            if (context instanceof BaseActivity) {
                mActivity = (BaseActivity) context;
            }
            init();
            initPaint();
        }
    
        /** 初始化一些常量 */
        private void init() {
            System.out.println("init");
            //把一个值从dip转换成px
            mIndicatorHeight = UiUtil.dip2px(mIndicatorHeight);
            mDividerPadding = UiUtil.dip2px(mDividerPadding);
            mTabPadding = UiUtil.dip2px(mTabPadding);
            mDividerWidth = UiUtil.dip2px(mDividerWidth);
            mTabTextSize = UiUtil.dip2px(mTabTextSize);
            //创建一个scroller
    //        mScroller =new Scroller(mActivity);
            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.addOnPageChangeListener(mPageListener);
    //        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(ViewPager.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.NORMAL));
            tab.setTextColor(UiUtil.getColorStateList(mTabTextColorResId,mActivity));
    //        tab.setBackgroundDrawable(UiUtil.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);
            selectTab(0);
        }
    
        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);
            selectTab(0);
        }
    
        /** 测量时的回调 */
        @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) {
            System.out.println("selectTab");
            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 ViewPager.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();
        }
    }

    bg_tab_color.xml

    <?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/text_blue1"/>
        <item android:color="@color/text_gray1"/>
    </selector>

    bg_tab_text.xml

    <?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/text_blue1"/>
        <item android:color="@color/text_gray1"/>
    </selector>

    使用步骤:

    Activity布局如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent"
        >
        <com.my.widget.PagerTab
            android:id="@+id/pt_tab"
            android:background="@color/white"
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="40dp"/>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/vp_notice"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    代码如下:

            MyAdapter noticeAdapter =  new MyAdapter (getSupportFragmentManager(),this);
            viewPager.setAdapter(noticeAdapter);
            pagerTab.setViewPager(viewPager);
    
  • 相关阅读:
    Android自定义view绘图
    编写一个函数,计算三个数字的大小,按从小到大的顺序输出。
    步进电机驱动控制
    细心!SQL语句进行运算时使用字符串时缺失精度的细节!
    好书摘要!免锁容器
    浅谈!SQL语句中LEFT JOIN ON WHERE和LEFT JOIN ON AND的区别
    解决!同一ajax请求获取的图片路径,在谷歌浏览器能正确展示图片,在火狐浏览器则显示路径undefined
    提问!同一ajax请求获取的图片路径,在谷歌浏览器能正确展示图片,在火狐浏览器则显示路径undefined
    2017.03.19随笔
    ECMAScript 数据类型
  • 原文地址:https://www.cnblogs.com/loaderman/p/9679913.html
Copyright © 2020-2023  润新知