在很多情況下,圓形進度條讓我們看起來比較美觀、簡潔,但Android的控件並沒有提供這樣的View,所以這需要我們自定義,以下就是我自己實現的View,請大神們多多指教哈。現在我們先來看幾張效果圖,懶得去做動態圖了,見諒啊:
用戶可以自定義文字、圖標,背景顏色,字體顏色等,廢話不多說,現在我們來了解下是怎麼實現的。
其實也很簡單,主要分爲三個部分,第一部分繪製圓形實心背景,第二部繪製外部圓形進度條,第三部繪製中間文字或者圖標。首先我們自定一個RoundProgressView繼承View,然後在onDraw實現繪製:
float paddingLeft = getPaddingLeft();
float paddingRight = getPaddingRight();
float paddingTop = getPaddingTop();
float paddingBottom = getPaddingBottom();
//draw the background
float left = paddingLeft + mBorderWidth;
float top = paddingTop + mBorderWidth;
float right = getWidth() - paddingRight - mBorderWidth;
float bottom = getHeight() - paddingBottom - mBorderWidth;
RectF oval = new RectF(left, top, right, bottom);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(mBackgroundColor);
mPaint.setStrokeWidth(0);
canvas.drawArc(oval, 0, 360, true, mPaint);
繪製圓形實心背景,其中,oval是該圓形所在的矩形, mPaint需要設置style,值爲FILL_AND_STROKE,表示填充內部和畫邊,Canvas爲我們提供了方法drawArc繪製圓弧,這裏我們是繪製0-360度,全部繪製成背景。
//draw the progress
left = paddingLeft + mBorderWidth / 2;
top = paddingTop + mBorderWidth / 2;
right = getWidth() - paddingRight - mBorderWidth / 2;
bottom = getHeight() - paddingBottom - mBorderWidth / 2;
oval = new RectF(left, top, right, bottom);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mBorderWidth);
mPaint.setColor(mBorderColor);
canvas.drawArc(oval, -90, mCurrentAngle, false, mPaint);
接下來繪製外層的進度圓弧,不同的地方mPaint的style設置成STROKE,畫邊。還有需要說明的是我們是-90度開始的,表明從最頂部開始繪製。
背景和圓弧進度繪製完後,我們就可以在正中間繪製文本或者圖片(bitmap),實現如下:
//draw text
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.setStrokeWidth(0);
mPaint.setTextAlign(Paint.Align.CENTER);
//get font info by paint
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
// calculate font height
float fontHeight = fontMetrics.bottom - fontMetrics.top;
// calculate font baseline
float textBaseY = getHeight() / 2 + fontHeight / 2 -fontMetrics.bottom;
canvas.drawText(value, getWidth() / 2, textBaseY, mPaint);
//draw bitmap
if (null == mMatrix) {
mMatrix = new Matrix();
//scale
mMatrix.postScale(mBitmapScale, mBitmapScale);
float dx = (getWidth() * (1 - mBitmapScale)) / 2.0f;
float dy = (getHeight() * (1 - mBitmapScale)) / 2.0f;
mMatrix.postTranslate(dx, dy);
}
canvas.drawBitmap(mBitmap, mMatrix, mPaint);
繪製文本的難點在於居中繪製,有的人還不知道textBaseY是怎麼算的,這裏給大家介紹一篇博文:Android Canvas drawText實現中文垂直居中
繪製圖片的難點在於計算大小,我這裏是根據View的比例來的,也就是mBitmapScale這個參數,默認我取2/5,用戶可以自定義。
使用方法(庫)我放在github上:https://github.com/linqssonny/RoundProgressView