文章目录
简介效果思路关键代码先画完整的弧线,图中红色曲线再画指示器部分的弧线,图中深蓝色弧线
不足源码[github](https://github.com/Super-Bin/HornetNestView.git)
简介
Android高仿马蜂窝Tabbar波浪线,tabbar的部分直接使用FlycoTabLayout这个库,很早以前用过,重点也不在这tabbar功能,主要是如何绘制tabbar下方的波浪线。
效果
可以直接看github
思路
波浪线的实现,可以借助二阶贝塞尔曲线。先画出一整条波浪线,然后再截取其中蓝色的线段,监听ViewPager的滑动,来改变截取的起始点,看起来就像会动的波浪线。
关键代码
其中
黄色框,表示一个tab的宽度深蓝色的弧线,表示指示器indicator的宽度浅蓝色线,表示指示器indicator与tab的间距
先画完整的弧线,图中红色曲线
int distance
, lastDistance
= 0;
int indicatorTop
= getHeight() - indicatorHeight
;
int indicatorBottom
= getHeight();
int startY
= (indicatorBottom
- indicatorTop
) / 2 + indicatorTop
;
for (int i
= 0; i
< this.mTabCount
; i
++) {
View currentTabView
= mTitleContainer
.getChildAt(i
);
float left
= currentTabView
.getLeft();
float right
= currentTabView
.getRight();
distance
= (int) ((right
- left
- indicatorWidth
) / 2);
Log
.i(TAG
, "left = " + left
);
Log
.i(TAG
, "right = " + right
);
if (i
== 0) {
mPath
.moveTo(left
+ distance
, startY
);
mPath
.rQuadTo(indicatorWidth
/ 2, indicatorHeight
/ 2, indicatorWidth
, 0);
mArcMeasure
.setPath(mPath
, false);
mArcPathLength
= mArcMeasure
.getLength();
Log
.i(TAG
, "一段圆弧的长度 mArcPathLength = " + mArcPathLength
);
} else {
int nextX
= (distance
+ lastDistance
) / 2;
mPath
.rQuadTo(nextX
, -indicatorHeight
, distance
+ lastDistance
, 0);
mPath
.rQuadTo(indicatorWidth
/ 2, indicatorHeight
/ 2, indicatorWidth
, 0);
}
lastDistance
= distance
;
}
mPaint
.setColor(Color
.RED
);
canvas
.drawPath(mPath
, mPaint
);
再画指示器部分的弧线,图中深蓝色弧线
灰色框表示一个完整的周期,红色线相当于有三个完整的周期+最后一个下划线的曲线长度
mMeasure
.setPath(mPath
, false);
mPathLength
= mMeasure
.getLength();
...
float startD
= 0;
float cycleLength
= (mPathLength
- mArcPathLength
)/ (this.mTabCount
- 1);
Log
.i(TAG
, "cycleLength = " + cycleLength
);
startD
= this.mCurrentTab
* cycleLength
+ cycleLength
* this.mCurrentPositionOffset
;
if(startD
< 0) {
startD
= 0;
}
Log
.i(TAG
, "startD = " + startD
);
mMeasure
.getSegment(startD
, startD
+ mArcPathLength
, mDstPath
, true);
mPaint
.setColor(Color
.BLUE
);
canvas
.drawPath(mDstPath
, mPaint
);
不足
目前的情况只适用,是在保证每一个tab的宽度相等、而且每一个指示器长度indicator也相等的情况下。不同Tab宽度、不同指示器indicato长度还没做,不过可以根据以上的思路进行修改就能达到目的。
源码github