您的位置:首页 > 移动开发 > Android开发

android 自定义view 圆形进度条

2015-06-09 10:25 686 查看

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

}


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

项目源码,点击下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: