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

来源:互联网 发布:显示器校准软件 编辑:程序博客网 时间:2024/04/29 20:09

项目中很多时候时候会用到圆形的进度条,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版

0 0
原创粉丝点击