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;
}
}
}
代码都加了非常多的注释,因为本人菜鸟,所以知道没有注释阅读起来的痛苦。
项目源码,点击下载相关文章推荐
- android开发环境安装与配置
- 如何获取Android唯一标识(唯一序列号)
- Android studio导入项目(出现的问题)
- Android安卓中循环录像并检测内存卡容量
- Android编译系统参考手册
- Android Studio 快捷键(MAC)
- Android实战简易教程-第十二枪(ViewFlipper实现幻灯效果)
- Android中3种全屏方法及3种去掉标题栏的方法
- Android图片的固定大小展示
- Android短信发送和接收流程源码分析
- 【转】Universal-Image-Loader(android图片缓存)
- Android布局文件layout.xml的一些属性值
- Android练习—修改背景颜色
- Android练习——Spinner二级联动_城市选择
- Android实现电话拨号器和短信发送器
- Android 实现页面跳转并传递参数
- Android布局
- [Android Studio 权威教程]AS添加第三方库的6种方式(Jar,module,so等)
- Android手机保持屏幕高亮方法
- Android常用代码段