Android自定义View——弧线展示图

来源:互联网 发布:以房养老不可行数据 编辑:程序博客网 时间:2024/05/22 03:41

前面我也写了有几个自定义进度的控件,那么,今天,我再加一个控件,原理跟前面讲的差不多,先看看效果:
这里写图片描述

这个是一个以弧线为依托的进度控件,主要包括了两个圆弧、一个圆、一个文本。
当我们点击开始按钮的时候,会出现一个动画,逐渐的出现进度,好了,下面开始我们的编码。

新建一个类,继承自View,实现三个构造方法,接着定义变量,初始化变量的数据。代码如下:

private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint;    private float length;    private float mRadius;    private float mCircleXY;    private float mSweepValue = 0;    private String mShowText = "0%";    private RectF mRectF;    public MViewOne(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView();    }    public MViewOne(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    public MViewOne(Context context) {        super(context);        initView();    }    private void initView() {        mArcPaint = new Paint();        mArcPaint.setStrokeWidth(50);        mArcPaint.setAntiAlias(true);        mArcPaint.setColor(Color.GREEN);        mArcPaint.setStyle(Style.STROKE);        mCirclePaint = new Paint();        mCirclePaint.setColor(Color.GREEN);        mCirclePaint.setAntiAlias(true);        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setColor(Color.RED);        mTextPaint.setStrokeWidth(0);        mPaint = new Paint();        mPaint.setStrokeWidth(40);        mPaint.setAntiAlias(true);        mPaint.setColor(Color.YELLOW);        mPaint.setStyle(Style.STROKE);    }

可以看到,这里一共定义了四个画笔,两个画弧形,一个画文本,还有一个绘制圆。

在我们的onSizeChange方法里面,再给变量赋值。

    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        length = w;        mCircleXY = length / 2;        mRadius = (float) (length * 0.5 / 2);    }

这时候,圆的半径、圆的起绘点,都已经有值了。

下面开始绘制

@Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 画圆        mRectF = new RectF((float) (length * 0.1), (float) (length * 0.1),                (float) (length * 0.9), (float) (length * 0.9));        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);        // 画弧线        canvas.drawArc(mRectF, 270, 360, false, mPaint);        canvas.drawArc(mRectF, 270, mSweepValue, false, mArcPaint);        // 绘制文字        float textWidth = mTextPaint.measureText(mShowText);   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间        canvas.drawText(mShowText, (int)(length/2-textWidth/2), (int)(length/2+textWidth/2) , mTextPaint);    }

这个时候,全部的效果已经出来了,但是这个还是静态的,对外暴露一个方法,让数据可以动态的刷新

    public void setProgress(float mSweepValue) {        float a = (float) mSweepValue;        if (a != 0) {            this.mSweepValue = (float) (360.0 * (a / 100.0));            mShowText = mSweepValue + "%";            Log.e("this.mSweepValue:", this.mSweepValue + "");        } else {            this.mSweepValue = 25;            mShowText = 25 + "%";        }        invalidate();    }

好了,所有的代码都在这里了,老规矩,最后我贴上全部的代码:

public class MViewOne extends View {    private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint;    private float length;    private float mRadius;    private float mCircleXY;    private float mSweepValue = 0;    private String mShowText = "0%";    private RectF mRectF;    public MViewOne(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView();    }    public MViewOne(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    public MViewOne(Context context) {        super(context);        initView();    }    private void initView() {        mArcPaint = new Paint();        mArcPaint.setStrokeWidth(50);        mArcPaint.setAntiAlias(true);        mArcPaint.setColor(Color.GREEN);        mArcPaint.setStyle(Style.STROKE);        mCirclePaint = new Paint();        mCirclePaint.setColor(Color.GREEN);        mCirclePaint.setAntiAlias(true);        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setColor(Color.RED);        mTextPaint.setStrokeWidth(0);        mPaint = new Paint();        mPaint.setStrokeWidth(40);        mPaint.setAntiAlias(true);        mPaint.setColor(Color.YELLOW);        mPaint.setStyle(Style.STROKE);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        length = w;        mCircleXY = length / 2;        mRadius = (float) (length * 0.5 / 2);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 画圆        mRectF = new RectF((float) (length * 0.1), (float) (length * 0.1),                (float) (length * 0.9), (float) (length * 0.9));        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);        // 画弧线        canvas.drawArc(mRectF, 270, 360, false, mPaint);        canvas.drawArc(mRectF, 270, mSweepValue, false, mArcPaint);        // 绘制文字        float textWidth = mTextPaint.measureText(mShowText);   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间        canvas.drawText(mShowText, (int)(length/2-textWidth/2), (int)(length/2+textWidth/2) , mTextPaint);    }    public void setProgress(float mSweepValue) {        float a = (float) mSweepValue;        if (a != 0) {            this.mSweepValue = (float) (360.0 * (a / 100.0));            mShowText = mSweepValue + "%";            Log.e("this.mSweepValue:", this.mSweepValue + "");        } else {            this.mSweepValue = 25;            mShowText = 25 + "%";        }        invalidate();    }}

谢谢阅读,学习重在坚持,贵在坚持。

2 0
原创粉丝点击