Android自定义TabLayout,神奇效果竟是如此简单
前言

思路分析
草图如下:

代码实现
//最左边的图形Path pathLeft = new Path();pathLeft.lineTo(textWidth, 0);pathLeft.cubicTo(textWidth + arcControlX, arcControlY, textWidth + arcWidth - arcControlX, viewHeight - arcControlY, textWidth + arcWidth, viewHeight);pathLeft.lineTo(0, viewHeight);pathLeft.lineTo(0, 0);paint.setColor(selectColor);canvas.drawPath(pathLeft, paint);
首先我们的起始点坐标是(0,0),到坐标(textWidth, 0) 画一条直线;
然后三阶贝塞尔曲线,2个控制点的坐标1(textWidth + arcControlX,arcControlY),坐标2(textWidth + arcWidth - arcControlX,viewHeight - arcControlY),结束的坐标(textWidth + arcWidth,viewHeight);
最后画直线到坐标点(0, viewHeight),再到最终的原点(0, 0)。
//中间的图形Path pathCenter = new Path();pathCenter.moveTo(tabPosition * textWidth + tabPosition * arcWidth, 0);pathCenter.cubicTo(tabPosition * textWidth + tabPosition * arcWidth - arcControlX, arcControlY, tabPosition * textWidth + tabPosition * arcWidth - arcWidth + arcControlX, viewHeight - arcControlY, tabPosition * textWidth + tabPosition * arcWidth - arcWidth, viewHeight);pathCenter.lineTo(tabPosition * textWidth + tabPosition * arcWidth + textWidth + arcWidth, viewHeight);pathCenter.cubicTo(tabPosition * textWidth + tabPosition * arcWidth + textWidth + arcWidth - arcControlX, viewHeight - arcControlY, tabPosition * textWidth + tabPosition * arcWidth + textWidth + arcControlX, arcControlY, tabPosition * textWidth + tabPosition * arcWidth + textWidth, 0);pathCenter.lineTo(tabPosition * textWidth + tabPosition * arcWidth, 0);paint.setColor(selectColor);canvas.drawPath(pathCenter, paint);
//最右边的图形Path pathRight = new Path();pathRight.moveTo(viewWidth, 0);pathRight.lineTo(viewWidth - textWidth, 0);pathRight.cubicTo(viewWidth - textWidth - arcControlX, arcControlY, viewWidth - textWidth - arcWidth + arcControlX, viewHeight - arcControlY, viewWidth - textWidth - arcWidth, viewHeight);pathRight.lineTo(viewWidth, viewHeight);pathRight.lineTo(viewWidth, 0);paint.setColor(selectColor);canvas.drawPath(pathRight, paint);
for (int i = 0; i < tabTextList.size(); i++) {String strTabText = tabTextList.get(i);Rect rectText = new Rect();textPaint.getTextBounds(strTabText, 0, strTabText.length(), rectText);int strWidth = rectText.width();int strHeight = rectText.height();if (i == 0) {canvas.drawText(strTabText, (textWidth + arcWidth / 2) / 2 - strWidth / 2, viewHeight / 2 + strHeight / 2, textPaint);} else if (i == tabTextList.size() - 1) {canvas.drawText(strTabText, viewWidth - (textWidth + arcWidth / 2) / 2 - strWidth / 2, viewHeight / 2 + strHeight / 2, textPaint);} else {canvas.drawText(strTabText, textWidth * i + arcWidth * (i - 1) + (textWidth + 2 * arcWidth) / 2 - strWidth / 2, viewHeight / 2 + strHeight / 2, textPaint);}}
@Overridepublic boolean onTouchEvent(MotionEvent event) {boolean isHandleClick = false;//是否处理点击事件switch (event.getAction()) {case MotionEvent.ACTION_DOWN:float x = event.getX();float y = event.getY();System.out.println("YPKTabLayoutView.onTouchEvent x=" + x + " y=" + y);for (int i = 0; i < tabNumber; i++) {if (x <= ((i + 1) * textWidth + i * arcWidth + arcWidth / 2)) {//点击的第一个按钮tabPosition = i;if (onTabClickListener != null) {onTabClickListener.tabSelectedListener(tabPosition);}invalidate();isHandleClick = true;break;}}return isHandleClick;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:break;}return super.onTouchEvent(event);}
远程依赖使用
一:添加依赖
Add it in your root build.gradle at the end of repositories:
allprojects {repositories {...maven { url 'https://jitpack.io' }}}
Add the dependency
dependencies {implementation 'com.github.dacaoyuan:YPKTabDemo:1.0.2'}
二:在xml布局中添加
<com.ypk.library.view.YPKTabLayoutViewandroid:id="@+id/mYPKTabLayoutView"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"app:view_bg_corners="0"app:arcControlX="30" />
三:代码中
val tabTextList: MutableList<String> = ArrayList<String>()tabTextList.add("推荐学习");tabTextList.add("企业学院");tabTextList.add("我的关注");mYPKTabLayoutView.setTabTextList(tabTextList);mYPKTabLayoutView.addTabSelectedListener { tabPosition ->val makeText =Toast.makeText(this@MainActivity,"点击了第" + tabPosition + "项",Toast.LENGTH_SHORT)makeText.setGravity(Gravity.CENTER, 0, 0);makeText.show();}
属性说明

评论
