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); // 根據進度畫圓弧
}
}