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以及偏移量,这个感觉没法写多出来,有兴趣的可以自己算算。
如有错误,请留言更正,以免误导其他开发者!!!