android 自定义view 圆形进度条

来源:互联网 发布:php sleep 毫秒 编辑:程序博客网 时间:2024/04/30 19:54

前几天,公司来了一个项目,要做一个特别炫酷的界面,进度条呢就是其中之一了,用系统的进度条,然后光靠修改资源背景是达不到需求的,那就只好自己画一个了,我一个菜鸟,第一次听说要自自己画的时候我是拒绝的,因为我不是说画就能画出来的,首先我没有画过,所以我要找找网上有没有有没有类似的源码,百度一搜索,duang,duang,就看到xiaanming大神的博客了(http://blog.csdn.net/xiaanming/article/details/10298163),很好,还提供了了源码下载,我于是在源码的基础上进行了二次开发吧(向大神以及所有开源的同胞致敬),同时文章最后将会提供demo下载,现在先来浏览下效果图吧。






<span style="white-space:pre"></span>protected void onDraw(Canvas canvas) {super.onDraw(canvas);/** * 画最外层的大圆环 */int centre = getWidth() / 2; // 获取圆心的x坐标int radius = (int) (centre - roundWidth / 2); // 圆环的半径paint.setColor(roundColor); // 设置圆环的颜色paint.setStyle(Paint.Style.STROKE); // 设置空心paint.setStrokeWidth(roundWidth); // 设置圆环的宽度paint.setAntiAlias(true); // 消除锯齿canvas.drawCircle(centre, centre, radius, paint); // 画出圆环Log.e("log", centre + "");/** * 画进度百分比 */paint.setStrokeWidth(0);paint.setColor(textColor);paint.setTextSize(textSize);paint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体int percent = (int) (((float) progress / (float) max) * 100); // 中间的进度百分比,先转换成float在进行除法运算,<span style="white-space:pre"></span>不然都为0float textWidth = paint.measureText(percent + "%"); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间if (textIsDisplayable && percent != 0 && style == STROKE) {canvas.drawText(percent + "%", centre - textWidth / 2, centre+ textSize / 2, paint); // 画出进度百分比}paint.setStyle(Paint.Style.FILL_AND_STROKE); // 设置实心paint.setStrokeWidth(0);paint.setColor(Color.WHITE);/** * 画圆弧 ,画圆环的进度 */// 设置进度是实心还是空心paint.setStrokeWidth(roundWidth); // 设置圆环的宽度paint.setColor(roundProgressColor); // 设置进度的颜色RectF oval = new RectF(centre - radius, centre - radius, centre+ radius, centre + radius); // 用于定义的圆弧的形状和大小的界限(个人理解就是求圆的直径上的俩点的<span style="white-space:pre"></span>坐标值)switch (style) {case STROKE: {paint.setStyle(Paint.Style.STROKE);// 设置圆弧的线帽为圆形,这个也可以提出来当成自定义属性,自由度更广更方便paint.setStrokeCap(Paint.Cap.ROUND);canvas.drawArc(oval, 270, 360 * progress / max, false, paint); // 根据进度画圆弧,270度是12点钟方向//进度是刚开始还是已经结束了,用于判断在起始位置是否绘制圆点boolean isstartorstop = Math.sin(Math.toRadians(270 + 360* progress / max)) == -1;paint.setStyle(Paint.Style.FILL);paint.setColor(Color.WHITE);// 绘制12点钟和6点钟方向的圆点,绘制圆点的最重要的是要根据已知的条件算出圆点的圆心坐标if (topandbuttomcircle) {if (isdismisscircle) {if (!isstartorstop) {// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx1 = (float) (centre + radius* Math.cos(Math.toRadians(270)));float cy1 = (float) (centre + radius* Math.sin(Math.toRadians(270)));canvas.drawCircle(cx1, cy1, roundWidth / 2, paint);float cx11 = (float) (centre + radius* Math.cos(Math.toRadians(270)));float cy11 = (float) (centre + radius* Math.sin(Math.toRadians(270)));canvas.drawCircle(cx11, cy11, roundWidth / 4, paint);paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx2 = (float) (centre + radius* Math.cos(Math.toRadians(90)));float cy2 = (float) (centre + radius* Math.sin(Math.toRadians(90)));canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);paint.setAlpha(255);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx21 = (float) (centre + radius* Math.cos(Math.toRadians(90)));float cy21 = (float) (centre + radius* Math.sin(Math.toRadians(90)));canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);}} else {// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx1 = (float) (centre + radius* Math.cos(Math.toRadians(270)));float cy1 = (float) (centre + radius* Math.sin(Math.toRadians(270)));canvas.drawCircle(cx1, cy1, roundWidth / 4, paint);paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx2 = (float) (centre + radius* Math.cos(Math.toRadians(90)));float cy2 = (float) (centre + radius* Math.sin(Math.toRadians(90)));canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);paint.setAlpha(255);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx21 = (float) (centre + radius* Math.cos(Math.toRadians(90)));float cy21 = (float) (centre + radius* Math.sin(Math.toRadians(90)));canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);}}// 绘制3点钟和9点钟方向的圆点if (leftandrightcircle) {if (isdismisscircle) {if (!isstartorstop) {paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx1 = (float) (centre + radius* Math.cos(Math.toRadians(0)));float cy1 = (float) (centre + radius* Math.sin(Math.toRadians(0)));canvas.drawCircle(cx1, cy1, roundWidth / 2, paint);paint.setAlpha(255);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx11 = (float) (centre + radius* Math.cos(Math.toRadians(0)));float cy11 = (float) (centre + radius* Math.sin(Math.toRadians(0)));canvas.drawCircle(cx11, cy11, roundWidth / 4, paint);paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx2 = (float) (centre + radius* Math.cos(Math.toRadians(180)));float cy2 = (float) (centre + radius* Math.sin(Math.toRadians(180)));canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);paint.setAlpha(255);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx21 = (float) (centre + radius* Math.cos(Math.toRadians(180)));float cy21 = (float) (centre + radius* Math.sin(Math.toRadians(180)));canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);}} else {paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx1 = (float) (centre + radius* Math.cos(Math.toRadians(0)));float cy1 = (float) (centre + radius* Math.sin(Math.toRadians(0)));canvas.drawCircle(cx1, cy1, roundWidth / 2, paint);paint.setAlpha(255);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx11 = (float) (centre + radius* Math.cos(Math.toRadians(0)));float cy11 = (float) (centre + radius* Math.sin(Math.toRadians(0)));canvas.drawCircle(cx11, cy11, roundWidth / 4, paint);paint.setAlpha(150);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx2 = (float) (centre + radius* Math.cos(Math.toRadians(180)));float cy2 = (float) (centre + radius* Math.sin(Math.toRadians(180)));canvas.drawCircle(cx2, cy2, roundWidth / 2, paint);paint.setAlpha(255);// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)float cx21 = (float) (centre + radius* Math.cos(Math.toRadians(180)));float cy21 = (float) (centre + radius* Math.sin(Math.toRadians(180)));canvas.drawCircle(cx21, cy21, roundWidth / 4, paint);}}// 绘制线头上的圆点,跟随进度旋转360度if (lineheadcircle) {// 如果在进度为零或者进度为100的时候不再绘制线头圆点if (!isstartorstop) {// 圆心为(a,b),半径为R,点A与到X轴的为角α,(a+R*cosα,b+R*sinα)// 角度加上270是为了使圆点在12点钟方向开始绘制,3点钟方向时默认时0度,顺时针方向角度依次<span style="white-space:pre"></span>增大。float cx = (float) (centre + radius* Math.cos(Math.toRadians(270 + 360 * progress/ max)));float cy = (float) (centre + radius* Math.sin(Math.toRadians(270 + 360 * progress/ max)));canvas.drawCircle(cx, cy, roundWidth / 4, paint);Log.e("Math.sin",""+ Math.sin(Math.toRadians(270 + 360* progress / max)));}}break;}case FILL: {paint.setStyle(Paint.Style.FILL_AND_STROKE);if (progress != 0)canvas.drawArc(oval, 270, 360 * progress / max, true, paint); // 根据进度画圆弧break;}}}

代码都加了非常多的注释,因为本人菜鸟,所以知道没有注释阅读起来的痛苦。



 项目源码,点击下载

0 0
原创粉丝点击