繪制圓環很多時候會用到Canvas的drawArc方法,
drawArc()方法的說明很簡單:
public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
第一個參數 oval:定義承載圓弧形狀的矩形。通過設置該矩形可以指定圓弧的位置和大小。
第二個參數 startAngle: 設置圓弧是從哪個角度順時針繪畫的。
第三個參數 sweepAngle: 設置圓弧順時針掃過的角度。
第四個參數 useCenter: 繪制的時候是否使用圓心,我們繪制圓弧的時候設置為false,如果設置為true, 並且當前畫筆的描邊屬性設置為Paint.Style.FILL的時候,畫出的就是扇形。
第五個參數 paint: 指定繪制的畫筆。
第一個誤區:繪制的起始角度和掃過的角度
例:起始角度為-90,滑過角度為120度的圓環
canvas.drawArc(oval,-90,120,false,mPaint);
注意起始的-90度在上部的中點位置。
第二個誤區:useCenter的作用
上面提過到,如果將畫筆的樣式設置為: mPaint.setStyle(Paint.Style.STROKE) 是看不出任何效果的。那么我們將畫筆的樣式設置為: mPaint.setStyle(Paint.Style.FILL) ,並分別將useCenter設置成false,true,觀察下效果:
將useCenter設置為false,不經過圓心:
將useCenter設置為true,經過圓心:
第三個誤區:如果該圓環有寬度,一定要注意繪制的起始位置
這點在使用drawCircle繪制時也需要注意:比如要畫一個半徑是50dip,路徑寬度為6dip的圓,如果使用下列的代碼去繪制:
mPaint.setColor(mDownloadBackgroundRingColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mDownloadBackgroundRingSize); float cx = mViewWidth / 2; float cy = mViewHeight / 2; float radius = mViewWidth / 2; canvas.drawCircle(cx, cy, radius, mPaint);
那么得到圓是這樣子的:
注意到它的四邊似乎少了一部分,這是因為一旦給圓設置了路徑寬度,便需要該路徑寬度也計算在內:所以這個圓的半徑事實上應該是:View寬度/2 - 路徑寬度/2, 只有這樣才能容納要繪制的View,否則多余的部分就看不見了。
將上面的代碼修改成:
mPaint.setColor(mDownloadBackgroundRingColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mDownloadBackgroundRingSize); float cx = mViewWidth / 2; float cy = mViewHeight / 2; float radius = mViewWidth / 2 - mDownloadBackgroundRingSize / 2; canvas.drawCircle(cx, cy, radius, mPaint);
這樣得到的圓就變成正常的了。
同樣,如果圓環也有路徑寬度,那么用於指定其位置的Rect也要注意繪制的起始位置。
// Draw background ring mPaint.setColor(mDownloadBackgroundRingColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mDownloadBackgroundRingSize); float cx = mViewWidth / 2; float cy = mViewHeight / 2; float radius = mViewWidth / 2 - mDownloadBackgroundRingSize / 2; canvas.drawCircle(cx, cy, radius, mPaint); // Draw progress ring mPaint.setColor(mDownloadProgressBarColor); float margin = mDownloadBackgroundRingSize / 2; mDownloadBackgroundRingRect.set(margin, margin, mViewWidth - margin, mViewHeight - margin); canvas.drawArc(mDownloadBackgroundRingRect, -90, 90, false, mPaint);
下面這張圖可能表達的更為清楚: