前言
自从安卓支持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,觉得对您有帮助就给个星吧!
码字不易,期待各位的赞赏!!!