自定义圆形进度条是一个很简单的项目,开发起来没什么难度,但非常适合练手,现在说一下开发思路吧!
实现效果:
实现思路:
1,画出默认圆环
2,在默认圆环基础上画进度圆环
3,在中心画文字
实现步骤:
在values下创建attrs文件,并自定义属性,分析属性有:默认圆环颜色,进度圆环颜色,圆半径,圆环宽度,字体大小等
<!--自定义圆形进度条-->
<declare-styleable name="CustomProgress">
<attr name="radius" format="dimension" /><!--半径-->
<attr name="strokeWidth" format="dimension" /><!--画笔宽度-->
<attr name="defaultColor" format="color" /><!--默认环形颜色-->
<attr name="progressColor" format="color" /><!--进度条颜色-->
<attr name="totalProgress" format="integer" /><!--总进度-->
<attr name="textColor" format="color|reference" /><!--字体颜色-->
<attr name="mTextSize" format="dimension"/><!--字体大小-->
</declare-styleable>
然后获取属性
public ArcView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array=context.getTheme().obtainStyledAttributes(attrs,R.styleable.CustomProgress,0,0);
try {
radius=array.getDimension(R.styleable.CustomProgress_radius,200);
strokeWidth=array.getDimension(R.styleable.CustomProgress_strokeWidth,40);
totalProgress=array.getInt(R.styleable.CustomProgress_totalProgress,100);
defaultColor=array.getColor(R.styleable.CustomProgress_defaultColor,Color.GREEN);
progressColor=array.getColor(R.styleable.CustomProgress_totalProgress,Color.RED);
textColor=array.getColor(R.styleable.CustomProgress_textColor,Color.BLACK);
mTextSize=array.getDimensionPixelSize(R.styleable.CustomProgress_mTextSize,28);
} finally {
array.recycle();
}
init();
}
private void init() {
mPaint=new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);//抗锯齿
mPaint.setDither(true);//防抖动
}
重写ondraw方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(textColor);
mPaint.setTextSize(mTextSize);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
String text = "";
if (mProgress == totalProgress) {
text = "下载成功!";
} else {
text = (int) (((float) mProgress / (float) totalProgress) * 100) + "%";
}
float textWidth = mPaint.measureText(text, 0, text.length());
canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + mTextSize / 2, mPaint);
mPaint.setColor(defaultColor);
mPaint.setStrokeWidth(strokeWidth);
mPaint.setStyle(Paint.Style.STROKE);
RectF rectfs = new RectF();
rectfs.top = getHeight() / 2 - radius;
rectfs.bottom = getHeight() / 2 + radius;
rectfs.left = getWidth() / 2 - radius;
rectfs.right = getWidth() / 2 + radius;
canvas.drawArc(rectfs, 0, 360, false, mPaint);
mPaint.setColor(progressColor);
mPaint.setStrokeWidth(strokeWidth);
mPaint.setStyle(Paint.Style.STROKE);
RectF rectf = new RectF();
rectf.top = getHeight() / 2 - radius;
rectf.bottom = getHeight() / 2 + radius;
rectf.left = getWidth() / 2 - radius;
rectf.right = getWidth() / 2 + radius;
canvas.drawArc(rectf, 0, mProgress * 360 / totalProgress, false, mPaint);
}
刷新进度,在主页面设置进度,因为是耗时操作,故要开启线程
final ArcView view= (ArcView) findViewById(R.id.arcview);
new Thread(new Runnable() {
@Override
public void run() {
while (progress<=100){
progress+=3;
view.setProgress(progress);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
设置进度
/**
* 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
* 刷新界面调用postInvalidate()能在非UI线程刷新
* @param progress
*/
public synchronized void setProgress(int progress) {
if(progress < 0){
throw new IllegalArgumentException("progress not less than 0");
}
if(progress > totalProgress){
progress = totalProgress;
}
if(progress <= totalProgress){
this.mProgress = progress;
postInvalidate();
}
}
效果:
改变一下ondraw()。换种风格
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.CYAN);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(getWidth()/2,getHeight()/2,radius,mPaint);
mPaint.setColor(textColor);
mPaint.setTextSize(mTextSize);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
String text = "";
if (mProgress == totalProgress) {
text = "下载成功!";
} else {
text = (int) (((float) mProgress / (float) totalProgress) * 100) + "%";
}
float textWidth = mPaint.measureText(text, 0, text.length());
canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + mTextSize / 2, mPaint);
mPaint.setColor(defaultColor);
mPaint.setStrokeWidth(strokeWidth);
mPaint.setStyle(Paint.Style.STROKE);
RectF rectfs = new RectF();
rectfs.top = getHeight() / 2 - radius;
rectfs.bottom = getHeight() / 2 + radius;
rectfs.left = getWidth() / 2 - radius;
rectfs.right = getWidth() / 2 + radius;
canvas.drawArc(rectfs, 0, 360, false, mPaint);
mPaint.setColor(progressColor);
mPaint.setStrokeWidth(strokeWidth);
mPaint.setStyle(Paint.Style.STROKE);
RectF rectf = new RectF();
rectf.top = getHeight() / 2 - radius;
rectf.bottom = getHeight() / 2 + radius;
rectf.left = getWidth() / 2 - radius;
rectf.right = getWidth() / 2 + radius;
canvas.drawArc(rectf, 0, mProgress * 360 / totalProgress, false, mPaint);
}
效果:
注释掉默认圆环效果
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.CYAN);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(getWidth()/2,getHeight()/2,radius,mPaint);
mPaint.setColor(textColor);
mPaint.setTextSize(mTextSize);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
String text = "";
if (mProgress == totalProgress) {
text = "下载成功!";
} else {
text = (int) (((float) mProgress / (float) totalProgress) * 100) + "%";
}
float textWidth = mPaint.measureText(text, 0, text.length());
canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + mTextSize / 2, mPaint);
// mPaint.setColor(defaultColor);
// mPaint.setStrokeWidth(strokeWidth);
// mPaint.setStyle(Paint.Style.STROKE);
// RectF rectfs = new RectF();
// rectfs.top = getHeight() / 2 - radius;
// rectfs.bottom = getHeight() / 2 + radius;
// rectfs.left = getWidth() / 2 - radius;
// rectfs.right = getWidth() / 2 + radius;
// canvas.drawArc(rectfs, 0, 360, false, mPaint);
mPaint.setColor(progressColor);
mPaint.setStrokeWidth(strokeWidth);
mPaint.setStyle(Paint.Style.STROKE);
RectF rectf = new RectF();
rectf.top = getHeight() / 2 - radius;
rectf.bottom = getHeight() / 2 + radius;
rectf.left = getWidth() / 2 - radius;
rectf.right = getWidth() / 2 + radius;
canvas.drawArc(rectf, 0, mProgress * 360 / totalProgress, false, mPaint);
}
效果:
也可以让圆环在内圆外侧,将圆形半径减去圆环宽度的一半即可,看效果。
实心圆进度条:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// mPaint.setColor(Color.CYAN);
// mPaint.setStyle(Paint.Style.FILL);
// canvas.drawCircle(getWidth()/2,getHeight()/2,radius-strokeWidth/2,mPaint);
mPaint.setColor(defaultColor);
mPaint.setStrokeWidth(2);
mPaint.setStyle(Paint.Style.STROKE);
RectF rectfs = new RectF();
rectfs.top = getHeight() / 2 - radius;
rectfs.bottom = getHeight() / 2 + radius;
rectfs.left = getWidth() / 2 - radius;
rectfs.right = getWidth() / 2 + radius;
canvas.drawArc(rectfs, 0, 360, false, mPaint);
mPaint.setColor(progressColor);
// mPaint.setStrokeWidth(strokeWidth);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
RectF rectf = new RectF();
rectf.top = getHeight() / 2 - radius;
rectf.bottom = getHeight() / 2 + radius;
rectf.left = getWidth() / 2 - radius;
rectf.right = getWidth() / 2 + radius;
canvas.drawArc(rectf, 0, mProgress * 360 / totalProgress, true, mPaint);
mPaint.setColor(textColor);
mPaint.setTextSize(mTextSize);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
String text = "";
if (mProgress == totalProgress) {
text = "下载成功!";
} else {
text = (int) (((float) mProgress / (float) totalProgress) * 100) + "%";
}
float textWidth = mPaint.measureText(text, 0, text.length());
canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + mTextSize / 2, mPaint);
}
效果:
基础知识可以参考:
https://github.com/GcsSloop/AndroidNote
源码下载地址:
http://download.csdn.net/detail/qq_16131393/9622840