Android -- 自定義View小Demo,動態畫圓(一)


1,轉載:(http://blog.csdn.NET/lmj623565791/article/details/24500107),現在如下圖的效果:

由上面的效果圖可以看到其實是一個在一個圓上換不同的顏色繪制圓弧,這樣的話我們來先看一下我們自定義的話需要提供什么

1,提供兩種顏色

2,提供圓弧的寬度

3,繪制的圓弧的速度

OK,現在開始來自定義我們的屬性,創建attrs文件,添加以下代碼,反別代表第一種顏色、第二種顏色、圓弧寬度、圓弧繪制的速度

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleView">
        <attr name="firstColor" format="color"/>
        <attr name="secondColor" format="color"/>
        <attr name="circleWidth" format="dimension"/>
        <attr name="speed" format="integer"/>
    </declare-styleable>
</resources>

再來編寫我們的自定義view

CircleView.java

這里先給大家簡單介紹一下Canvas drawArc()的簡單實用吧,首先看一下參數

public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
oval :指定圓弧的外輪廓矩形區域。
startAngle: 圓弧起始角度,單位為度。
sweepAngle: 圓弧掃過的角度,順時針方向,單位為度。
useCenter: 如果為True時,在繪制圓弧時將圓心包括在內,通常用來繪制扇形。
paint: 繪制圓弧的畫板屬性,如顏色,是否填充等。

所以通過創建對應圓弧大小的RectF即可解決繪制,代碼如下,一些解釋很詳細

package com.qianmo.circleview.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.qianmo.circleview.R;

/**
 * Created by wangjitao on 2016/10/14 0014.
 * 自定義View的幾個步驟
 * 1,自定義View屬性
 * 2,在View中獲得我們的自定義的屬性
 * 3,重寫onMeasure
 * 4,重寫onDraw
 * 5,重寫onLayout(這個決定view放置在哪兒)
 */
public class CircleView extends View {
    /**
     * 第一種顏色
     */
    private int mFirstColor;
    /**
     * 第二種顏色
     */
    private int mSecondColor;
    /**
     * 圓弧的寬度
     */
    private int mCircleWidth;
    /**
     * 畫筆
     */
    private Paint mPaint;
    /**
     * 圓弧的度數
     */
    private int mProgress;
    /**
     * 圓弧繪制的速度
     */
    private int mSpeed;
    /**
     * 是不是開始繪制下一個圓弧
     */
    private boolean isNext = false;

    public CircleView(Context context) {
        this(context, null);
    }

    public CircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * 獲取自定義控件的一些值
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleView, defStyleAttr, 0);

        for (int i = 0; i < a.getIndexCount(); i++) {

            switch (a.getIndex(i)) {
                case R.styleable.CircleView_firstColor:
                    mFirstColor = a.getColor(a.getIndex(i), Color.WHITE);
                    break;
                case R.styleable.CircleView_secondColor:
                    mSecondColor = a.getColor(a.getIndex(i), Color.RED);
                    break;
                case R.styleable.CircleView_speed:
                    mSpeed = a.getInt(a.getIndex(i), 20);
                    break;
                case R.styleable.CircleView_circleWidth:
                    mCircleWidth = a.getDimensionPixelOffset(a.getIndex(i), (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));
                    break;
            }
        }
        a.recycle();
        mPaint = new Paint();

        //繪圖線程
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    mProgress++;
                    if (mProgress == 360) {
                        mProgress = 0;
                        if (!isNext) {
                            isNext = true;
                        } else {
                            isNext = false;
                        }
                    }
                    postInvalidate();
                    try {
                        Thread.sleep(mSpeed); //通過傳遞過來的速度參數來決定線程休眠的時間從而達到繪制速度的快慢
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int center = getWidth() / 2;
        int radius = center - mCircleWidth / 2;
        mPaint.setStrokeWidth(mCircleWidth); // 設置圓環的寬度
        mPaint.setAntiAlias(true); // 消除鋸齒
        mPaint.setStyle(Paint.Style.STROKE); // 設置空心
        RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); // 用於定義的圓弧的形狀和大小的界限

        if (!isNext) {// 第一顏色的圈完整,第二顏色跑
            mPaint.setColor(mFirstColor); // 設置圓環的顏色
            canvas.drawCircle(center, center, radius, mPaint); // 畫出圓環
            mPaint.setColor(mSecondColor); // 設置圓環的顏色
            canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根據進度畫圓弧
        } else {
            mPaint.setColor(mSecondColor); // 設置圓環的顏色
            canvas.drawCircle(center, center, radius, mPaint); // 畫出圓環
            mPaint.setColor(mFirstColor); // 設置圓環的顏色
            canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根據進度畫圓弧
        }
    }
}

 下面是自己改了一下寫的小demo,先看一下效果吧

 

代碼如下:

package com.qianmo.circleview.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.qianmo.circleview.R;

/**
 * Created by wangjitao on 2016/10/14 0014.
 * 慢慢的繪制一個圓
 */
public class CircleViewOne extends View {
    /**
     * 第一種顏色
     */
    private int mFirstColor;
    /**
     * 圓弧的寬度
     */
    private int mCircleWidth;
    /**
     * 畫筆
     */
    private Paint mPaint;
    /**
     * 圓弧的度數
     */
    private int mProgress;
    /**
     * 圓弧繪制的速度
     */
    private int mSpeed;

    /**
     * 是否繼續繪制
     */
    private boolean isDrawCircle = true;


    public CircleViewOne(Context context) {
        this(context, null);
    }

    public CircleViewOne(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * 獲取自定義控件的一些值
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public CircleViewOne(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleViewOne, defStyleAttr, 0);

        for (int i = 0; i < a.getIndexCount(); i++) {

            switch (a.getIndex(i)) {
                case R.styleable.CircleViewOne_color:
                    mFirstColor = a.getColor(a.getIndex(i), Color.WHITE);
                    break;
                case R.styleable.CircleViewOne_drawSpeed:
                    mSpeed = a.getInt(a.getIndex(i), 20);
                    break;
                case R.styleable.CircleViewOne_circleWidthOne:
                    mCircleWidth = a.getDimensionPixelOffset(a.getIndex(i), (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));
                    break;
            }
        }
        a.recycle();
        mPaint = new Paint();

        //繪圖線程
        new Thread() {
            @Override
            public void run() {
                while (isDrawCircle) {
                    mProgress++;
                    if (mProgress == 360) {
                        isDrawCircle = false;
                    } else {
                        isDrawCircle = true;
                        postInvalidate();
                        try {
                            Thread.sleep(mSpeed); //通過傳遞過來的速度參數來決定線程休眠的時間從而達到繪制速度的快慢
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }


                }
            }
        }.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int center = getWidth() / 2;
        int radius = center - mCircleWidth / 2;
        mPaint.setStrokeWidth(mCircleWidth); // 設置圓環的寬度
        mPaint.setAntiAlias(true); // 消除鋸齒
        mPaint.setStyle(Paint.Style.STROKE); // 設置空心
        RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius); // 用於定義的圓弧的形狀和大小的界限

        mPaint.setColor(mFirstColor); // 設置圓環的顏色
        canvas.drawArc(oval, -90, mProgress, false, mPaint); // 根據進度畫圓弧
    }
}

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM