1. 程式人生 > >Android自定義View——弧線展示圖

Android自定義View——弧線展示圖

前面我也寫了有幾個自定義進度的控制元件,那麼,今天,我再加一個控制元件,原理跟前面講的差不多,先看看效果:
這裡寫圖片描述

這個是一個以弧線為依託的進度控制元件,主要包括了兩個圓弧、一個圓、一個文字。
當我們點選開始按鈕的時候,會出現一個動畫,逐漸的出現進度,好了,下面開始我們的編碼。

新建一個類,繼承自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();
    }

}

謝謝閱讀,學習重在堅持,貴在堅持。