MaterialProgressDrawable的繪製
MaterialProgressDrawable是一個自定義的Drawable,需要重寫一下一個方法:- draw:繪製圖形
- setAlpha:設置透明度
- setColorFilter:設置填充色
- getOpacity:獲取不透明度
- getIntrinsicWidth、getIntrinsicHeight:獲取Drawable的寬高
我們直接看最重要的代碼:
@Override
public void draw(Canvas c) {
final Rect bounds = getBounds();
final int saveCount = c.save();
c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
mRing.draw(c, bounds);
c.restoreToCount(saveCount);
}
MaterialProgressDrawable在它需要重寫的draw方法中調用了mRing.draw(c, bounds);
mRing是一個內部類,是畫圓環和三角形的主要類,bounds很重要,它指定了所畫圖形所在的內切矩形
在Ring這個內部類的draw方法中調用瞭如下兩個方法:
c.drawArc(arcBounds, startAngle, sweepAngle, false, mPaint);
drawTriangle(c, startAngle, sweepAngle, bounds);
第一行是畫一個圓環,參數的含義:
arcBounds:圓環的內切矩形
startAngle:圓環的起始位置
sweepAngle:圓環的偏移量
boolean:false表示的是弧形,true表示的是扇形
mPaint:畫筆
第二行是畫一個三角形,核心代碼:
float inset = (int) mStrokeInset / 2 * mArrowScale;
float x = (float) (mRingCenterRadius * Math.cos(0) + bounds.exactCenterX());
float y = (float) (mRingCenterRadius * Math.sin(0) + bounds.exactCenterY());
// Update the path each time. This works around an issue in SKIA
// where concatenating a rotation matrix to a scale matrix
// ignored a starting negative rotation. This appears to have
// been fixed as of API 21.
mArrow.moveTo(0, 0);
mArrow.lineTo(mArrowWidth * mArrowScale, 0);
mArrow.lineTo((mArrowWidth * mArrowScale / 2), (mArrowHeight
* mArrowScale));
mArrow.offset(x - inset, y);
mArrow.close();
// draw a triangle
mArrowPaint.setColor(mCurrentColor);
c.rotate(startAngle + sweepAngle - ARROW_OFFSET_ANGLE, bounds.exactCenterX(),
bounds.exactCenterY());
c.drawPath(mArrow, mArrowPaint);
x、y和inset是爲了計算這個三角形的偏移量,好讓這個三角形和圓環對接到一起,這裏面的難的不是畫,而是各種計算mArrowWidth、mArrowScale以及偏移量,這個感覺沒法寫多出來,有興趣的可以自己算算。
如有錯誤,請留言更正,以免誤導其他開發者!!!