一个用于轮播的ViewPagerIndicator

效果图:

一个用于轮播的ViewPagerIndicator_第1张图片

用法:

viewPager = (ViewPager) getView().findViewById(R.id.viewPager);
viewPager.setAdapter(new BannerAdapter());
indicator = (ViewPagerIndicator) getView().findViewById(R.id.indicator);
indicator.attachViewPager(viewPager);

轮播间隔可在xml中设置(interval_time属性)
也可在jav代码中设置:
indicator.setIntervalTime(4000);

代码:

    public class ViewPagerIndicator extends View implements ViewPager.OnPageChangeListener, View.OnTouchListener {
        private final String TAG = getClass().getSimpleName();
        /**
         * 绑定的ViewPager
         */
        private ViewPager mViewPager;
        /**
         * 每一页的间隔时间
         */
        private int intervalTime;
        /**
         * 圆点个数
         */
        private int mSize;
        /**
         * 圆点半径(控件高度的一半)
         */
        private int mDotRadius;
        /**
         * 两个圆水平距离
         */
        private int mHorizontalSpacing;
        /**
         * 两个圆心水平距离
         */
        private int mDistanceOfDot;
        /**
         * pager 滑动偏移量
         */
        private float positionOffset;
        /**
         * 当前pager
         */
        private int position;
        private Paint mPaint;
        /**
         * 圆点基础色
         */
        private int mBaseColor;
        /**
         * 当前圆点颜色
         */
        private int mCurrentColor;
        /**
         * 是否需要轮播
         */
        private boolean mNeedLoop;

        /**
         * 和一个ViewPager 绑定
         */
        public void attachViewPager(ViewPager mViewPager) {
            if (mViewPager == null) return;
            this.mViewPager = mViewPager;
            mViewPager.addOnPageChangeListener(this);
            mSize = mViewPager.getAdapter().getCount();
            if (mSize > 1) {
                invalidate();
                if (mNeedLoop) {
                    mViewPager.setOnTouchListener(this);
                    needSwitchPage = true;
                    postDelayed(nextPage, intervalTime);
                }
            }
        }

        /**
         * 设置每次轮播间隔
         */
        public void setIntervalTime(int intervalTime) {
            this.intervalTime = intervalTime;
        }

        public ViewPagerIndicator(Context context) {
            super(context);
            init(null);
        }

        public ViewPagerIndicator(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);
        }

        public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(attrs);
        }

        private void init(AttributeSet attrs) {
            TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);
            intervalTime = ta.getInt(R.styleable.ViewPagerIndicator_interval_time, 2000);
            mBaseColor = ta.getColor(R.styleable.ViewPagerIndicator_base_color, Color.parseColor("#90D3C1B3"));
            mCurrentColor = ta.getColor(R.styleable.ViewPagerIndicator_selected_color, Color.WHITE);
            mNeedLoop = ta.getBoolean(R.styleable.ViewPagerIndicator_need_loop, true);
            ta.recycle();
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            nextPage = new NextPageRunnable();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (mSize <= 1) return;
            //画基础圆点
            int firstDotLeft = ((getWidth() - mSize * 2 * mDotRadius - mHorizontalSpacing * (mSize - 1)) / 2);
            int startX = firstDotLeft;
            mPaint.setColor(mBaseColor);
            for (int i = 0; i < mSize; i++) {
                canvas.drawCircle(startX + mDotRadius, getHeight() / 2, mDotRadius, mPaint);
                startX += mDistanceOfDot;
            }
            //画选中的圆点
            mPaint.setColor(mCurrentColor);
            canvas.drawCircle(firstDotLeft + mDotRadius + (int) (mDistanceOfDot * positionOffset) + position
                    * mDistanceOfDot, getHeight() / 2, mDotRadius, mPaint);
            Log.d(TAG, "onDraw");
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            this.positionOffset = positionOffset;
            this.position = position;
            invalidate();
        }

        @Override
        public void onPageSelected(int position) {
            Log.d(TAG, "onPageScrolled " + position);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }

        private NextPageRunnable nextPage;
        private boolean needSwitchPage;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            removeCallbacks(nextPage);
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN://接收触摸事件时停止轮播
                    needSwitchPage = false;
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP://手指松开时继续轮播
                    needSwitchPage = true;
                    postDelayed(nextPage, intervalTime);
                    break;
            }
            return false;
        }

        /**
         * 下一页
         */
        private class NextPageRunnable implements Runnable {
            @Override
            public void run() {
                if (!needSwitchPage || getVisibility() != VISIBLE || mViewPager == null || !mNeedLoop)
                    return;
                int currentItem = mViewPager.getCurrentItem();
                if (currentItem < mViewPager.getAdapter().getCount() - 1) {
                    currentItem++;
                } else {
                    currentItem = 0;
                }
                mViewPager.setCurrentItem(currentItem);// 切换到下一个页面
                removeCallbacks(nextPage);
                postDelayed(nextPage, intervalTime);
            }
        }

        @Override
        protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
            super.onVisibilityChanged(changedView, visibility);
            if (!mNeedLoop) return;
            if (visibility == VISIBLE) {
                needSwitchPage = true;
                postDelayed(nextPage, intervalTime);
            } else {
                needSwitchPage = false;
                removeCallbacks(nextPage);
            }
            Log.d(TAG, "onVisibilityChanged visibility:" + visibility);
        }

        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            needSwitchPage = false;
            removeCallbacks(nextPage);
        }

        /**
         * 初始化圆点尺寸 水平间隔
         */
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mDotRadius = h / 2;
            mHorizontalSpacing = (int) (mDotRadius * 1.5f);
            mDistanceOfDot = mDotRadius * 2 + mHorizontalSpacing;
        }
    }

几个自定义属性:


        
        
        
        

你可能感兴趣的:(一个用于轮播的ViewPagerIndicator)