项目中,我们经常需要用到环形进度条,比如说下载进度,QQ上加载图片的那个进度环,其实这个很好实现,今天我就给大家分享一个我在实际项目中自己写的一个环形进度条,感觉很方便实用,大家如有什么好的想法或者问题,可以跟我联系,我们共同讨论进步。首先我们看一下效果图:
源码其实很简单,就一个类,继承自View,让我们看下源码
/*
* 自定义环形进度条 KSCircleProgressBar
*
* Author:KevinStudio
* mailto:kevinstudiohelp@gmail.com
*/
package com.example.circleprogressbardemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
public class KSCircleProgressBar extends View {
public int max = 360;// 最大进度值
public int progress = 0;// 当前进度值
public float startAngle = -90;// 进度条从什么角度开始
private int myWidth = 0;// view宽度
private int myHeight = 0;// view高度
private int circleSize = 10;// 进度环的宽度
private int textSize = 16;// 进度文本大小
private int frontCircleColor = Color.WHITE;// 进度环前端颜色
private int backCircleColor = Color.TRANSPARENT;// 进度环后端颜色
private int textColor = frontCircleColor;// 进度文本字体颜色
private String progressInfo = ""; // 进度信息 可自定义文本信息 默认如90%
private boolean isShowProgressText = true; // 是否显示进度信息
private boolean isCustomProgressInfo = false;// 是否使用自定义进度文本
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint txtPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF rectF = null;
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
invalidate();
}
public int getProgress() {
return progress;
}
public float getStartAngle() {
return startAngle;
}
public void setStartAngle(float startAngle) {
this.startAngle = startAngle;
}
public int getCircleSize() {
return circleSize;
}
public void setCircleSize(int circleSize) {
paint.setStrokeWidth(circleSize);
this.circleSize = circleSize;
}
public int getTextSize() {
return textSize;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
txtPaint.setTextSize(textSize);
}
public String getProgressInfo() {
return progressInfo;
}
public void setProgressInfo(String progressInfo) {
this.progressInfo = progressInfo;
}
public void setProgress(int progress) {
this.progress = progress;
invalidate();
}
public KSCircleProgressBar(Context context) {
super(context);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(circleSize);
paint.setAntiAlias(true);
txtPaint.setStyle(Style.STROKE);
txtPaint.setTextSize(textSize);
txtPaint.setAntiAlias(true);
}
public KSCircleProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(circleSize);
paint.setAntiAlias(true);
txtPaint.setStyle(Style.STROKE);
txtPaint.setTextSize(textSize);
txtPaint.setAntiAlias(true);
max = attrs.getAttributeIntValue(null, "max", 360);
progress = attrs.getAttributeIntValue(null, "progress", 0);
}
public KSCircleProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(circleSize);
paint.setAntiAlias(true);
txtPaint.setStyle(Style.STROKE);
txtPaint.setTextSize(textSize);
txtPaint.setAntiAlias(true);
max = attrs.getAttributeIntValue(null, "max", 360);
progress = attrs.getAttributeIntValue(null, "progress", 0);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
if (w > 0 && h > 0) {
myWidth = w;
myHeight = h;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制后端背景进度环
paint.setColor(backCircleColor);
canvas.drawCircle(myWidth / 2, myHeight / 2,
(myWidth > myHeight ? myHeight : myWidth) / 2 - circleSize / 2,
paint);
// 绘制前端进度环
paint.setColor(frontCircleColor);
if (rectF == null) {
rectF = new RectF();
}
rectF.left = circleSize / 2;
rectF.right = myWidth - circleSize / 2;
rectF.top = circleSize / 2;
rectF.bottom = myHeight - circleSize / 2;
if (progress != 0) {
canvas.drawArc(rectF, startAngle, 360f * progress / max, false,
paint);
}
// 绘制进度信息
if (!isCustomProgressInfo) {
progressInfo = progress * 100 / max + "%";
}
if (isShowProgressText) {
txtPaint.setColor(textColor);
float l = txtPaint.measureText(progressInfo);
if (l > myWidth - circleSize * 2) {
txtPaint.setTextSize(txtPaint.getTextSize()
* (myWidth - circleSize * 2) / l * 0.9f);
l = txtPaint.measureText(progressInfo);
}
canvas.drawText(progressInfo, myWidth / 2 - l / 2, myHeight / 2
+ txtPaint.getTextSize() / 2, txtPaint);
}
}
public boolean isShowProgressText() {
return isShowProgressText;
}
public void setShowProgressText(boolean isShowProgressText) {
this.isShowProgressText = isShowProgressText;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public boolean isCustomProgressInfo() {
return isCustomProgressInfo;
}
public void setCustomProgressInfo(boolean isCustomProgressInfo) {
this.isCustomProgressInfo = isCustomProgressInfo;
}
public int getFrontCircleColor() {
return frontCircleColor;
}
public void setFrontCircleColor(int frontCircleColor) {
this.frontCircleColor = frontCircleColor;
}
public int getBackCircleColor() {
return backCircleColor;
}
public void setBackCircleColor(int backCircleColor) {
this.backCircleColor = backCircleColor;
}
}
使用也很简单,用布局文件或者代码生成都可以:
这是布局文件的一个示例
好了,是不是很简单呢,另外大家还可以自己修改代码进行定制,比如画饼形进度条等,欢迎大家提出宝贵意见。
附类文件和demo下载地址
点击下载 :KSCircleProgressBar.java