Android 圆角TabLayout

1,627 阅读1分钟

前言

      自从安卓支持Fragment之后,TabHost(TabLayout)+ViewPager+Fragment 用于实现多个页面左右切换的功能被很多app采用,但是大多是对原生组件的应用或者简单封装,比如都是块状的,这里分享整理一个之前自己开发的一个圆角的TabLayout,对您如果有帮助的话github上给个星,喜欢一下本文吧!

正文

      国际惯例先看图吧:


具体的思路就是通过集成一个水平布局的LinearLayout,难点就是要要与ViewPager的滚动速率一致,形成过渡效果,关键代码如下:

/**
 * 设置关联的ViewPager
 *
 * @param viewPager
 */
public void setupWithViewPager(ViewPager viewPager) {
    switchViewPager(viewPager);
    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            mCurrentPosition = position;
            if (isEnabled()) {
                highLightTextView(position);
            }
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            scroll(position, positionOffset);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    });
    initIndicatorDrawable();
}

重点看下ViewPager.OnPageChangeListener的onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,以向右滑为例,positionOffset从0到1的增大过程对应的是滑动的比例,因此可以作为计算过渡的参数,代码如下:

public void scroll(int position, float offset) {
    if (getChildCount() == 0) return;
    View selectView = getChildAt(position);
    int width = selectView.getMeasuredWidth();
    if (width == 0) return;
    if (mIndicatorDrawable != null ){
        mIndicatorDrawable.setBounds(0, getPaddingTop(), width, getHeight() - getPaddingBottom());
    }

    mIndicatorTravelOffset = (int) (selectView.getX() + width * offset);
    invalidate();
}

mIndicatorTravelOffset 保存了当前滑动tab的水平位置,在通过 invalidate();条用ondraw()方法,进而调用drawIndicatorVerticalPos()方法,如下:

protected void drawIndicatorVerticalPos(Canvas canvas) {
    if (mIndicatorDrawable != null) {
        canvas.save();
        canvas.translate(mIndicatorTravelOffset, 0);
        mIndicatorDrawable.draw(canvas);
        canvas.restore();
    }
}

通过 canvas.translate(mIndicatorTravelOffset, 0);实现实时绘制圆角。想通了整个过程实现还是蛮简单的。代码github,觉得对您有帮助就给个星吧!

码字不易,期待各位的赞赏!!!