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

Android 自定义View、ViewGroup 实战训练之CircleProgress

2014-09-18 09:57 357 查看
项目中很多时候时候会用到圆形的进度条,Android系统自带的不太好看,通常我们都会去自定义它,今天我们来介绍一下自定义控件以及自定义属性的使用。

先来看一下自定义CircleProgress的代码,如果你看着太吃力,请先阅读一下《Android
自定义View、ViewGroup(一)之工作原理》

public class CircleProgress extends View {

public static final int STROKE = 0;
public static final int FILL = 1;

private Paint paint;

private int circleColor;
private int progressColor;
private int textColor;
private float textSize;
private float circleWidth;
private int circleMax;
private boolean textIsDisplay;
private int style;

/**
* 当前进度
*/
private int progress;

public CircleProgress(Context context) {
this(context, null);
}

public CircleProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

paint = new Paint();
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
//获取自定义属性和默认值
circleColor = mTypedArray.getColor(R.styleable.CircleProgressBar_circle_color, Color.RED);
progressColor = mTypedArray.getColor(R.styleable.CircleProgressBar_circle_progress_color, Color.GREEN);
textColor = mTypedArray.getColor(R.styleable.CircleProgressBar_text_color, Color.GREEN);
textSize = mTypedArray.getDimension(R.styleable.CircleProgressBar_text_size, 15);
circleWidth = mTypedArray.getDimension(R.styleable.CircleProgressBar_circle_width, 5);
circleMax = mTypedArray.getInteger(R.styleable.CircleProgressBar_circle_max, 100);
textIsDisplay = mTypedArray.getBoolean(R.styleable.CircleProgressBar_is_text_display, true);
style = mTypedArray.getInt(R.styleable.CircleProgressBar_style, 0);

mTypedArray.recycle();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

//1.画出最外层的大圆环
int center = getWidth()/2;
int radius = (int) (center-circleWidth/2);
paint.setColor(circleColor); //设置圆环的颜色
paint.setStyle(Paint.Style.STROKE); //设置空心
paint.setStrokeWidth(circleWidth); //设置圆环的宽度
paint.setAntiAlias(true); //消除锯齿
canvas.drawCircle(center, center, radius, paint);

//2.画百分比
paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.DEFAULT_BOLD);
int percent = (int) (((float) progress / (float) circleMax) * 100);
float textWidth = paint.measureText(percent + "%");
if (isTextIsDisplay() && percent != 0 && style == STROKE) {
canvas.drawText(percent + "%", center - textWidth / 2, center + textSize / 2, paint);
}

//3.画进度
paint.setStrokeWidth(circleWidth);
paint.setColor(progressColor);
//用于定义的圆弧的形状和大小的界限
RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);

switch (style) {
case STROKE: {
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 0, 360 * progress / circleMax, false, paint);
break;
}
case FILL: {
paint.setStyle(Paint.Style.FILL_AND_STROKE);
if (progress != 0)
canvas.drawArc(oval, 0, 360 * progress / circleMax, true, paint);
break;
}
}
}

/**
* 设置进度
* @param progress
*/
public synchronized void setProgress(int progress){
if(progress < 0){
throw new IllegalArgumentException("progress not less than 0");
}
if(progress > circleMax){
progress = circleMax;
}
if(progress <= circleMax){
this.progress = progress;
postInvalidate();
}
}

/**
* 获取进度
* @return
*/
public synchronized int getProgress(){
return progress;
}

public synchronized int getCircleMax() {
return circleMax;
}

public synchronized void setCircleMax(int circleMax) {
if (circleMax < 0) {
throw new IllegalArgumentException("max not less than 0");
}
this.circleMax = circleMax;
}

public int getCircleColor() {
return circleColor;
}

public void setCircleColor(int circleColor) {
this.circleColor = circleColor;
}

public int getProgressColor() {
return progressColor;
}

public void setProgressColor(int progressColor) {
this.progressColor = progressColor;
}

public int getTextColor() {
return textColor;
}

public void setTextColor(int textColor) {
this.textColor = textColor;
}

public float getTextSize() {
return textSize;
}

public void setTextSize(float textSize) {
this.textSize = textSize;
}

public float getCircleWidth() {
return circleWidth;
}

public void setCircleWidth(float circleWidth) {
this.circleWidth = circleWidth;
}

public boolean isTextIsDisplay() {
return textIsDisplay;
}

public void setTextIsDisplay(boolean textIsDisplay) {
this.textIsDisplay = textIsDisplay;
}

public int getStyle() {
return style;
}

public void setStyle(int style) {
this.style = style;
}
}
步骤如下:

1. 定义类继承View重写构造方法并初始化画笔Paint

2. 根据Context的obtainStyledAttributes方法获取属性集,并获取自定义属性和默认值

3. 对外暴露get、set方法,让外部可以设置和获取指定值

4.重写onDraw方法画出大圆环、百分比和进度

如果想了解更多自定义进度条,请点击

下载Demo请猛戳 AndroidStudio版

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