自定义view之圆形进度条

来源:互联网 发布:淘宝网中学生绒衣 编辑:程序博客网 时间:2024/04/28 16:22

最近在练习自定义view,看了很多demo,关于自定义圆形进度条基本上大同小异。第一步先画一个背景圆,然后在背景圆的基础上画圆弧,圆弧画笔的宽度要和背景圆的画笔宽度一样,然后添加一个ValueAnimator动画进行重绘,来实现动画效果。效果图如下
这里写图片描述

画背景圆

  mArcRectF.set(mArcWidth / 2, mArcWidth / 2, getWidth() - mArcWidth / 2, getHeight() - mArcWidth / 2);        //画背景弧线        canvas.drawArc(mArcRectF, -90, 360, false, mArcBackPaint);

画圆弧

 //画百分比值弧线        canvas.drawArc(mArcRectF, -90, mSweepAngle, false, mArcForePaint);

attrs文件

<declare-styleable name="MyCircularProgressView">        <attr name="arcWidth" format="dimension" />        <attr name="scaleCount" format="integer" />        <attr name="startColor" format="color" />        <attr name="endColor" format="color" />        <attr name="labelText" format="string" />        <attr name="textColor" format="color" />        <attr name="progressTextSize" format="dimension" />        <attr name="labelTextSize" format="dimension" />    </declare-styleable>

完整代码

public class MyCircularProgressView extends View {    /* 弧线宽度 */    private float mArcWidth;    /* 渐变起始颜色 */    private int mStartColor;    /* 渐变终止颜色 */    private int mEndColor;    /* 渐变颜色数组 */    private int[] mColorArray;    /* 标签说明文本 */    private String mLabelText;    /* 文本颜色 */    private int mTextColor;    /* 百分比文本字体大小 */    private float mProgressTextSize;    /* 标签说明字体大小 */    private float mLabelTextSize;    /* 背景弧线画笔 */    private Paint mArcBackPaint;    /* 百分比值弧线画笔 */    private Paint mArcForePaint;    /* 刻度线画笔 */    private Paint mLinePaint;    /* 标签说明文本画笔 */    private Paint mLabelTextPaint;    /* 百分比文本画笔 */    private Paint mProgressTextPaint;    /* 弧线外切矩形 */    private RectF mArcRectF;    /* 测量文本宽高的矩形 */    private Rect mTextRect;    /* 百分比 */    private float mProgress;    /* 百分比对应角度 */    private float mSweepAngle;    public MyCircularProgressView(Context context) {        this(context, null);    }    public MyCircularProgressView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MyCircularProgressView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCircularProgressView, defStyleAttr, 0);        mArcWidth = ta.getDimension(R.styleable.MyCircularProgressView_arcWidth, DensityUtils.dp2px(context, 8));        mStartColor = ta.getColor(R.styleable.MyCircularProgressView_startColor, Color.parseColor("#3FC199"));        mEndColor = ta.getColor(R.styleable.MyCircularProgressView_endColor, Color.parseColor("#3294C1"));        mColorArray = new int[]{mStartColor, mEndColor};        mLabelText = ta.getString(R.styleable.MyCircularProgressView_labelText);        mTextColor = ta.getColor(R.styleable.MyCircularProgressView_textColor, Color.parseColor("#4F5F6F"));        mProgressTextSize = ta.getDimension(R.styleable.MyCircularProgressView_progressTextSize, 160);        mLabelTextSize = ta.getDimension(R.styleable.MyCircularProgressView_labelTextSize, 64);        ta.recycle();        mArcBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mArcBackPaint.setStyle(Paint.Style.STROKE);        mArcBackPaint.setStrokeWidth(mArcWidth);        mArcBackPaint.setColor(Color.LTGRAY);        mArcForePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mArcForePaint.setStyle(Paint.Style.STROKE);        mArcForePaint.setStrokeWidth(mArcWidth);        mArcForePaint.setStrokeCap(Paint.Cap.ROUND);        mArcRectF = new RectF();        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mLinePaint.setStyle(Paint.Style.STROKE);        mLinePaint.setColor(Color.WHITE);        mLinePaint.setStrokeWidth(DensityUtils.dp2px(context, 2));        mProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mProgressTextPaint.setStyle(Paint.Style.FILL);        mProgressTextPaint.setColor(mTextColor);        mProgressTextPaint.setTextSize(mProgressTextSize);        mLabelTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mLabelTextPaint.setStyle(Paint.Style.FILL);        mLabelTextPaint.setColor(mTextColor);        mLabelTextPaint.setTextSize(mLabelTextSize);        mTextRect = new Rect();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(measuredDimension(widthMeasureSpec), measuredDimension(heightMeasureSpec));    }    private int measuredDimension(int measureSpec) {        int result;        int mode = MeasureSpec.getMode(measureSpec);        int size = MeasureSpec.getSize(measureSpec);        if (mode == MeasureSpec.EXACTLY) {            result = size;        } else {            result = 800;            if (mode == MeasureSpec.AT_MOST) {                result = Math.min(result, size);            }        }        return result;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mArcRectF.set(mArcWidth / 2, mArcWidth / 2, getWidth() - mArcWidth / 2, getHeight() - mArcWidth / 2);        //画背景弧线        canvas.drawArc(mArcRectF, -90, 360, false, mArcBackPaint);        //设置渐变渲染        LinearGradient linearGradient = new LinearGradient(getWidth() / 2, 0, getWidth() / 2, getHeight(), mColorArray, null, Shader.TileMode.CLAMP);        mArcForePaint.setShader(linearGradient);        //画百分比值弧线        canvas.drawArc(mArcRectF, -90, mSweepAngle, false, mArcForePaint);        //画百分比文本        String progressText = mProgress + "%";        mProgressTextPaint.getTextBounds(progressText, 0, progressText.length(), mTextRect);        float progressTextWidth = mTextRect.width();        float progressTextHeight = mTextRect.height();        canvas.drawText(progressText, getWidth() / 2 - progressTextWidth / 2,                getHeight() / 2 + progressTextHeight / 2, mProgressTextPaint);        //画标签说明文本        mLabelTextPaint.getTextBounds(mLabelText, 0, mLabelText.length(), mTextRect);        canvas.drawText(mLabelText, getWidth() / 2 - mTextRect.width() / 2,                getHeight() / 2 - progressTextHeight / 2 - mTextRect.height(), mLabelTextPaint);    }    public void setProgress(float progress) {        ValueAnimator anim = ValueAnimator.ofFloat(mProgress, progress);        anim.setDuration((long) (Math.abs(mProgress - progress) * 20));        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mProgress = (float) animation.getAnimatedValue();                mSweepAngle = mProgress * 360 / 100;                mProgress = (float) (Math.round(mProgress * 10)) / 10;//四舍五入保留到小数点后两位                invalidate();            }        });        anim.start();    }}
原创粉丝点击