Android 自定义控件ViewPager 指示器 ViewPagerIndicator

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zuiaisha1/article/details/58604577

效果图

效果图

步骤

  1. 继承HorizontalScrollView
  2. 初始化必要属性与类
  3. 暴露方法 setTabDatum 根据数据 来创建tab
  4. 绑定ViewPager 根据ViewPager.setOnPageChangeListener来处理我们画Tab下划线的逻辑
  5. 在dispatchDraw中画线

实现

  1. 继承HorizontalScrollView
public class ViewPagerIndicator extends HorizontalScrollView 
  1. 初始化必要属性与类
    public ViewPagerIndicator(Context context) {
        this(context, null);
    }

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

    public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContainer = new LinearLayout(context);
        mContainer.setOrientation(LinearLayout.HORIZONTAL);
        addView(mContainer);
        init();
    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(mTabLineColor);
    }

    public int getScreenWidth() {
        WindowManager wm = (WindowManager) getContext().getSystemService(
                Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }
  1. 暴露方法 setTabDatum 根据数据 来创建tab
  // /****************** about tab *****************/


    /**
     *  2.  set tab datum in  ViewPagerIndicator
     * @param datum
     */
    public void setTabDatum(List<String> datum) {
        if (datum == null || datum.size() <= 0) {
            return;
        }
        mContainer.removeAllViews();
        mTabCount = datum.size();
        for (int i = 0; i < datum.size(); i++) {
            TextView view = createTab(datum.get(i));
            mContainer.addView(view);
            setTabClickListener(i, view);
        }
    }

    private void setTabClickListener(final int finalI, View view) {
        view.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mViewPager != null) {
                    mViewPager.setCurrentItem(finalI);
                }
            }
        });
    }

    private TextView createTab(String text) {
        TextView tv = new TextView(getContext());
        LayoutParams lp = new LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        lp.width = mTabWidth;
        tv.setGravity(Gravity.CENTER);
        tv.setTextColor(mTabTextColor);
        tv.setText(text);
        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTabTextSize);
        tv.setLayoutParams(lp);
        tv.setBackgroundColor(mTabBackgroundColor);
        return tv;
    }

    void resetAllTab() {
        for (int i = 0; i < mTabCount; i++) {
            View child = mContainer.getChildAt(i);
            if (child instanceof TextView) {
                ((TextView) child).setTextColor(mTabTextColor);
            }
        }
    }

    void setTabSelected(int position) {
        resetAllTab();
        View child = mContainer.getChildAt(position);
        if (child instanceof TextView) {
            ((TextView) child).setTextColor(mTabTextSelectedColor);
        }
    }
  1. 绑定ViewPager 根据ViewPager.setOnPageChangeListener来处理我们画Tab下划线的逻辑
///******************* about callback *******************/
    interface PageChangeListener {
        void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);

        void onPageSelected(int position);

        void onPageScrollStateChanged(int state);}
    private PageChangeListener onPageChangeListener;
    public void setOnPageChangeListener(PageChangeListener onPageChangeListener) {
        this.onPageChangeListener = onPageChangeListener;
    }

    /**
     * 1. bind ViewPager and set tab's position
     * @param viewPager
     * @param pos
     */
    public void bindViewPager(ViewPager viewPager, int pos) {
        mViewPager = viewPager;
        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                updateLine(position, positionOffset);


                if (onPageChangeListener != null) {
                    onPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
                }
            }

            @Override
            public void onPageSelected(int position) {
                setTabSelected(position);
                if (onPageChangeListener != null) {
                    onPageChangeListener.onPageSelected(position);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (onPageChangeListener != null) {
                    onPageChangeListener.onPageScrollStateChanged(state);
                }
            }
        });
        setTabSelected(pos);
        mViewPager.setCurrentItem(pos);
    }

    private void updateLine(int position, float positionOffset) {
        mTranslationX = (int) (getWidth() / mTabVisibleCount * (position + positionOffset));
        if (positionOffset > 0 && position >= (mTabVisibleCount - 2)
                && mContainer.getChildCount() > mTabVisibleCount) {
            if (mTabVisibleCount != 1) {
                this.scrollTo((int) ((position - (mTabVisibleCount - 2)) * mTabWidth
                        + (int) (mTabWidth * positionOffset)), 0);
            } else {
                this.scrollTo(
                        position * mTabWidth + (int) (mTabWidth * positionOffset), 0);
            }
        }
        invalidate();
    }
  1. 在dispatchDraw中画线

// /****************** about tab line *****************/

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        Rect rect = new Rect(
                //if it does not set lineWidth
                mTranslationX +
                        (mLineWidth == 0 ? 0 : mTabWidth / 2 - mLineWidth / 2),
                getMeasuredHeight() - mLineHeight,
                //if it does not set lineWidth
                mTranslationX +
                        (mLineWidth == 0 ? mTabWidth : mTabWidth / 2 + mLineWidth / 2),
                getMeasuredHeight());

        canvas.drawRect(rect, mPaint);
    }

具体使用

        mViewPagerIndicator = (ViewPagerIndicator) findViewById(R.id.vpi_container);
        mViewPager = (ViewPager) findViewById(R.id.vp_container);
//        1. bind ViewPager and set tab's position
        mViewPagerIndicator.bindViewPager(mViewPager, 0);

//        2.  set tab datum in  ViewPagerIndicator
        mViewPagerIndicator.setTabDatum(mDatum);

代码下载

https://github.com/agxxxx/ViewPagerIndicator

参考&&感谢

Hongyang 先生

猜你喜欢

转载自blog.csdn.net/zuiaisha1/article/details/58604577