自定义view之圆形进度条初体验

来源:互联网 发布:下载软件苹果助手 编辑:程序博客网 时间:2024/03/29 23:17

自定义圆形进度条是一个很简单的项目,开发起来没什么难度,但非常适合练手,现在说一下开发思路吧!

实现效果:

这里写图片描述

实现思路:

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

0 0
原创粉丝点击