看到别人一篇博文,实现一个自定义进度圆环,效果不错,决定临摹一下,加深学习。效果如下
基础api
Canvas这一块还是蛮复杂,并不大算一口把它啃下来,效果不好还费力。先一点点看方法文档吧
public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
Draw the specified arc, which will be scaled to fit inside the specified oval.
If the start angle is negative or >= 360, the start angle is treated as start angle modulo 360.
这是说画一段弧线,”inside”这个传入的矩形里,这个意思肯定是贴边的,术语叫什么内切线?起始角度如果大于360,取余。
参数
oval :指定圆弧的外轮廓矩形区域。
startAngle: 圆弧起始角度,单位为度。
sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。
useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。
paint: 绘制圆弧的画板属性,如颜色,是否填充等。
弧线花完了,剩下就是画个圆drawCircle,并在园里drawText。这两个比较简单,不细说。
text就是要显示进度progress,这样监听进度变更的时候调用我们自己设置的一个方法setProgress就行了
public void setProgress(int progress){
this.progress = progress;
postInvalidate();
}
这里主要是用postInvalidate重绘view,与invalidate的区别是可以在非ui线程调用。
让我头疼的是尝试了很多次都没有显示出来。后来才发现我没有在正确的位置调用getWidth。
我定义了一个成员变量mRadius,作为画圆的半径,构造函数里用getWidth给它赋值,但是这个时候自定义VIew还并没有执行onMeasure,这个时候getWidth亦或getHeigh都是0,所以我们不能在构造方法里赋值,那么在onDraw里赋值吗?
还有drawArc这个方法需要传入一个RectF,那么这个RectF对象显然是最好不要在onDraw中new出来,因为跟着进度改变不断重绘,onDraw也不不断被调用