自定义VIew——漂亮的圆形进度条
package com.example.firstapp; import java.text.DecimalFormat; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.View; /** * 自定义圆形进度条思路 * * 1.先画外圆,再画弧度, * 2.然后在画内圆 * 3.画文本信息 * 形成一个叠加的效果 */ public class MyProgressBar extends View { private FontMetrics fm; private Paint paint; /**内圆半径*/ private int inRadius; /**外圆半径*/ private int outRadius; /**文字的颜色*/ private int textColor=Color.rgb(20,131,214); /**内圆的颜色*/ private int inRdColor=Color.WHITE; /**外圆的颜色*/ private int outRdColor=Color.LTGRAY; /**进度条的颜色*/ private int proColor=Color.rgb(20,131,214); /**进度的最大值*/ private int max; /**当前进度条的值*/ private int progress; /**文字的大小*/ private int textSize=50; public MyProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { paint = new Paint(); } /*** * 设置内圆的半径 * * @param radius */ public void setInRadius(int radius) { this.inRadius = radius; } /*** * 设置外圆的半径 * * @param radius */ public void setOutRadius(int radius) { this.outRadius = radius; } /** * 设置进度条的颜色 默认蓝色 * * @param color */ public void setColor(int color) { this.textColor=color; } /*** * 设置文字的颜色值 默认蓝色 * * @param color */ public void setTextColor(int color) { this.textColor=color; } /*** * 设置进度条的最大值 * @param max */ public void setMax(int max) { this.max = max; } /*** * 设置当前进度条的进度值 * @param progress */ public void setProgress(int progress) { this.progress=progress; //设置进度之后,要求UI强制进行重绘 postInvalidate(); } /** * 设置文字的大小 * @param size */ public void setTextSize(int size){ this.textSize=size; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 获取控件的中心点 int cx = getWidth() / 2; int cy = getHeight() / 2; /*** * 1.画外圆 */ paint.setAntiAlias(true);// 设置画笔抗锯齿效果 paint.setColor(this.outRdColor); canvas.drawCircle(cx, cy, this.outRadius, paint); /*** * 2.画弧度 */ paint.setColor(this.proColor); // paint.setARGB(0, 25, 63, 155); // 圆形进度条的宽度就是外圆的半径减去内圆的半径 paint.setStrokeWidth(outRadius - inRadius); paint.setStyle(Paint.Style.STROKE);//设置弧度外填充 /** * 用于定义的圆弧的形状和大小的界限, 界限的计算:就是以外圆的正切圆的方式计算出,左上,右下的坐标值 * 有了中心点的坐标值cx,cy,也有了半径r那么 * * left=cx-外圆的半径 * top=cy-外圆的半径 * right=cx+外圆的半径 * bottom=cy+外圆的半径 * * 但这里要考虑一个问题是画笔有他本身的宽度,根据上面的思路把画笔的宽度问题,重新计算出圆弧的范围 */ int middle = (int) (paint.getStrokeWidth() / 2); RectF oval = new RectF(cx - outRadius + middle, cy - outRadius + middle, cx + outRadius - middle, cy + outRadius - middle); canvas.drawArc(oval, 0, 360 * this.progress / this.max, false, paint); // 根据进度画圆弧 /*** * 3.画内圆 */ paint.setStyle(Paint.Style.FILL); paint.setColor(this.inRdColor); canvas.drawCircle(cx, cy, this.inRadius, paint); /*** *4. 绘制文本 */ paint.setColor(this.textColor); paint.setStrokeWidth(5); paint.setTextSize(this.textSize); fm = paint.getFontMetrics(); //保留两位小数 DecimalFormat df = new DecimalFormat("#.00"); String numText=df.format(this.progress*1.0/max*100); // 测量文本的宽度 float textWidth = paint.measureText(numText) / 2; Log.d("progress", progress+""); float textCenterVerticalBaselineY = getHeight() / 2 - fm.descent + (fm.descent - fm.ascent) / 2; canvas.drawText(numText, cx - textWidth, textCenterVerticalBaselineY, paint); } }
![](http://images0.cnblogs.com/blog2015/536313/201504/151523297294746.png)