因为项目需要需要做几个自定义View,用到了Path,所以在结束后,总结分享下。
先看看效果吧。
大概就是一个防太阳运转的一个自定义view,还有一个是不规则曲线的进度条。
补充(2017-4-27)最终效果图
原理
SunProgressBar 找一个中心点画一个半圆,然后再创建一个矩形的Path路径,使用Path的op()方法,
然后用刚刚的半圆路径限制矩形路径,动态的绘制矩形大小,取共集,就做出了这个效果了。
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLine(canvas);
drawFilter(canvas);
drawProgressLogo(canvas);
}
//绘制中间填充的粉红色的部分
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void drawFilter(Canvas canvas) {
// mFilterRectF.right = (int) (mProgress * (mRectF.right - mRectF.left));
mFilterRectF.right = mProgressPoint.x;
Log.e("wwwww", "wwww" + mFilterRectF.right);
Path circlePath = new Path();
circlePath.addCircle(mCenterPoint.x, mCenterPoint.y, mRadius - bitmapPadding, Path.Direction.CW);
Path squrePath = new Path();
squrePath.addRect(mFilterRectF, Path.Direction.CW);
squrePath.op(circlePath, Path.Op.INTERSECT);
canvas.drawPath(squrePath, mFilterPaint);
}
LineProgress 给出一系列的不规则点,然后绘制一条灰色的贝塞尔曲线作为背景,然后再用PathMeasure 截取背景Path的部分长度,绘制进度条,随着进度的不断变化,然后截取的长度也在变化,就做出了一个动画
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLine(canvas);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void drawLine(Canvas canvas) {
Path path = new Path();
Path line2 = new Path();
final float point_unit_width = mMainRectF.right / mPoint_h.length;
for (int i = 0; i < mPoint_h.length - 1; i++) {
final int startX = (int) (i * point_unit_width);
final int startY = (int) (mMainRectF.bottom * mPoint_h[i]);
final int endX = (int) ((i + 1) * point_unit_width);
final int endY = (int) (mMainRectF.bottom * mPoint_h[i + 1]);
int wt = (startX + endX) / 2;
Point p3 = new Point();
Point p4 = new Point();
p3.y = startY;
p3.x = wt;
p4.y = endY;
p4.x = wt;
if (i == 0) {
path.moveTo(startX, startY);
line2.moveTo(startX, startY);
}
if (i == mPoint_h.length - 1)
line2.lineTo(endX, endY);
path.cubicTo(p3.x, p3.y, p4.x, p4.y, endX, endY);
}
canvas.drawPath(path, mBgPaint);
Path dst = new Path(); // 创建用于存储截取后内容的 Path
PathMeasure measure = new PathMeasure(path, false);
float stopD = measure.getLength() * mProgress;
float[] pos = new float[2];
float[] tan = new float[2];
measure.getPosTan(stopD, pos, tan);
measure.getSegment(0, stopD, dst, true);
canvas.drawPath(dst, mProgressPaint);
canvas.drawCircle(pos[0], pos[1], mLineWidth * 2, mProgressPaint);
}
OK,关键性的就写完了,如果大家感兴趣,可以下载我的Demo看看,因为我电脑的PS给卸载了,录屏转化不了了,所以LineProgress 给大家预览不了,后期我会补上的。
下面附上github连接地址,有需要的同学可以下载玩玩,代码及其简单,大家可以自己修改修改