代码如下:
//该方法必须在 Android 19以上的版本才能使用(Path.op()) @TargetApi(Build.VERSION_CODES.KITKAT) private void drawWave(Canvas canvas, Paint paint, Point[] points, float waveOffset) { mWaveLimitPath.reset(); mWavePath.reset(); //lockWave 用于判断波浪是否随进度条上涨下降 float height = lockWave ? 0 : mRadius - 2 * mRadius * mPercent; //moveTo和lineTo绘制出水波区域矩形 mWavePath.moveTo(points[0].x + waveOffset, points[0].y + height); for (int i = 1; i < mAllPointCount; i += 2) { mWavePath.quadTo(points[i].x + waveOffset, points[i].y + height, points[i + 1].x + waveOffset, points[i + 1].y + height); } mWavePath.lineTo(points[mAllPointCount - 1].x, points[mAllPointCount - 1].y + height); //不管如何移动,波浪与圆路径的交集底部永远固定,否则会造成上移的时候底部为空的情况 mWavePath.lineTo(points[mAllPointCount - 1].x, mCenterPoint.y + mRadius); mWavePath.lineTo(points[0].x, mCenterPoint.y + mRadius); mWavePath.close(); mWaveLimitPath.addCircle(mCenterPoint.x, mCenterPoint.y, mRadius, Path.Direction.CW); //取该圆与波浪路径的交集,形成波浪在圆内的效果 mWaveLimitPath.op(mWavePath, Path.Op.INTERSECT); canvas.drawPath(mWaveLimitPath, paint);以上,就实现了水波动态的效果,当然,你也可以通过配置,来设定水波是否随进度上涨下降。为了实现更好的效果,可以设置一个浅色的水波并支持设置水波的走向(R2L 和 L2R),通过设置浅色波浪和深色波浪动画的时间,从而实现长江后浪推前浪的效果,恩,效果很自然的~自己脑补从右至左波浪的实现和贝塞尔点的计算。
对获取坐标点的代码进行优化:
/** * 从左往右或者从右往左获取贝塞尔点 * * @return */ private Point[] getPoint(boolean isR2L, float waveWidth) { Point[] points = new Point[mAllPointCount]; //第1个点特殊处理,即数组的中点 points[mHalfPointCount] = new Point((int) (mCenterPoint.x + (isR2L ? mRadius : -mRadius)), mCenterPoint.y); //屏幕内的贝塞尔曲线点 for (int i = mHalfPointCount + 1; i < mAllPointCount; i += 4) { float width = points[mHalfPointCount].x + waveWidth * (i / 4 - mWaveNum); points[i] = new Point((int) (waveWidth / 4 + width), (int) (mCenterPoint.y - mWaveHeight)); points[i + 1] = new Point((int) (waveWidth / 2 + width), mCenterPoint.y); points[i + 2] = new Point((int) (waveWidth * 3 / 4 + width), (int) (mCenterPoint.y + mWaveHeight)); points[i + 3] = new Point((int) (waveWidth + width), mCenterPoint.y); } //屏幕外的贝塞尔曲线点 for (int i = 0; i < mHalfPointCount; i++) { int reverse = mAllPointCount - i - 1; points[i] = new Point((isR2L ? 2 : 1) * points[mHalfPointCount].x - points[reverse].x, points[mHalfPointCount].y * 2 - points[reverse].y); } //对从右向左的贝塞尔点数组反序,方便后续处理 return isR2L ? MiscUtil.reverse(points) : points; }至此,自定义圆形进度条相关的思路已全部讲述完成。代码已全部上传至 Git ,欢迎大家 Star 和 Fork,传送门:CircleProgress。
以上就是对于安卓开发方面的知识点简介,Android自定义View之圆形进度条总结,更多相关内容请继续关注拓胜科技安卓技术频道,或者需要了解拓胜安卓培训方面的问题,可以在线免费咨询拓胜教育老师。
本文出自广州拓胜科技,转载请务必保留此出处,谢谢合作!
拓胜愿景:自信成就好生活
拓胜校训:勤奋、实践、自信、责任心