Android 自定义控件ViewPager 指示器 ViewPagerIndicator

效果图

效果图

步骤

  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 先生

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值