仍是咱們自定View的那幾個步驟:html
一、本身定義View的屬性canvas
二、在View的構造方法中得到咱們本身定義的屬性數組
三、重寫onMesure (不是必須)
app
四、重寫onDrawide
本身定義View的屬性
post
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="firstColor" format="color" /> <attr name="secondColor" format="color" /> <attr name="circleWidth" format="dimension" /> <attr name="speed" format="integer" /> <declare-styleable name="progressStyle"> <attr name="firstColor"/> <attr name="secondColor"/> <attr name="circleWidth"/> <attr name="speed"/> </declare-styleable> </resources>this
public class ProgressView 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 ProgressView(Context context) { this(context, null); } public ProgressView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.progressStyle,defStyleAttr,0); int n = typedArray.getIndexCount(); for (int i =0 ;i < n ; i ++){ int attr =typedArray.getIndex(i); switch (attr){//這裏的0,1,2。3相應attrs中declare-styleable name="progressStyle"數組元素的順序。我是爲了舉例方便,實際開發中不要這樣寫 case 0: mFirstColor = typedArray.getColor(attr, Color.BLACK); break; case 1: mSecondColor = typedArray.getColor(attr, Color.RED); break; case 2: mCircleWidth = typedArray.getDimensionPixelSize(attr,(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16,getResources().getDisplayMetrics())); break; case 3: mSpeed = typedArray.getInt(attr,20); break; } } typedArray.recycle(); mPaint = new Paint(); startMyThread(); } @Override protected void onDraw(Canvas canvas) { int center = getWidth() / 2; // 獲取圓心的x座標 int radius = (center - mCircleWidth)/2 ;// 半徑 mPaint.setAntiAlias(true); mPaint.setStrokeWidth(mCircleWidth); mPaint.setStyle(Paint.Style.STROKE); RectF rectf = new RectF(center-radius,center-radius,center+radius,center+radius); //顏色的切換 if(!isNext){ canvas.save(); mPaint.setColor(mFirstColor);// 設置圓環的顏色 canvas.drawCircle(center,center,radius,mPaint);//劃出圓圈 mPaint.setColor(mSecondColor); canvas.drawArc(rectf,-90,mProgress,false,mPaint);//依據進度畫圓弧 canvas.restore(); }else { canvas.save(); mPaint.setColor(mSecondColor);// 設置圓環的顏色 canvas.drawCircle(center,center,radius,mPaint); mPaint.setColor(mFirstColor); canvas.drawArc(rectf,-90,mProgress,false,mPaint); canvas.restore(); } } private void startMyThread() { new Thread(new Runnable() { @Override public void run() { while (true){ mProgress++;//進度 if(mProgress == 360){//當360度時候值變爲初始狀態 mProgress = 0; if(!isNext){//設置是否切換顏色開關 isNext = true; }else { isNext = false; } } postInvalidate(); try { Thread.sleep(mSpeed); }catch (InterruptedException e){ e.printStackTrace(); } } } }).start();; } <strong> </strong>
以上代碼就是本身定義View的全部代碼,使用的話沒什麼多說的 直接在Xml中引用這個新建的ProgressView就可以了
spa
重畫ondraw 很少解釋直接看代碼rest
@Override protected void onDraw(Canvas canvas) { int center = getWidth() / 2; // 獲取圓心的x座標 int radius = (center - mCircleWidth)/2 ;// 半徑 mPaint.setAntiAlias(true); mPaint.setStrokeWidth(mCircleWidth); mPaint.setStyle(Paint.Style.STROKE); RectF rectf = new RectF(center-radius,center-radius,center+radius,center+radius); if(!isNext){ canvas.save(); mPaint.setColor(mFirstColor);// 設置圓環的顏色 canvas.drawCircle(center,center,radius,mPaint);//劃出圓圈 mPaint.setColor(mSecondColor); canvas.drawArc(rectf,-90,mProgress,false,mPaint);//依據進度畫圓弧 canvas.restore(); }else { canvas.save(); mPaint.setColor(mSecondColor);// 設置圓環的顏色 canvas.drawCircle(center,center,radius,mPaint); mPaint.setColor(mFirstColor); canvas.drawArc(rectf,-90,mProgress,false,mPaint); canvas.restore(); } }
因爲有的人說效果很是生硬,我就作了個完整的gif圖,速度是可以調節的,依據不一樣的速度值。移動可以調劑頻率
code