前言
这两天做的页面中有一个比较有意思的积分环,采用的是渐变形式,具体如下图所示。
真实效果图如下所示
下面就让我们来一步步实现它。
实现
首先,我们要明确我们要控制这个自定义View的哪些属性,可以分析出,我们需要控制环的粗细,环的进度,进度环的起始和结束色,背景环的起始和结束色,环的起始角度,环扫过的角度,有了这些参数,那么也就确定了其样式,顺便,我们再加一个是否显示动画的参数,具体attrs.xml文件内容如下所示。
下一步新建一个类ProgressRing,继承自View,我们实现其第二个构造函数
既然我们定义了那么多属性,那么在这个构造函数中我们就需要用到那些属性了,具体操作如下所示。
这里startAngle为何为150呢,也就是起始角度为150度,这150代表什么呢?因为我之后画圆环调用的是drawArc函数,我们跳转进去查看一下便可发现如下说明The arc is drawn clockwise. An angle of 0 degrees correspond to the geometric angle of 0 degrees (3 o'clock on a watch.),也就是说,零度角是在时钟三点钟方向,沿着顺时针方向角度依次增大,如果还不懂的话,那就看我下面这张图的分析。
所以sweepAngle为240大家也都知道了吧。
当然这都是默认值,具体数值你们可以自己定义,从而实现不同的圆弧。
我们进度最大为100,我们可以得到单位角度unitAngle = (float) (sweepAngle / 100.0);
我们分别设置两支画笔,bgPaint和progressPaint,一支画背景,一支画进度,并对他们设置样式,具体如下所示。
现在,我们最初的准备工作都做完了,下面就是来确定画的大小和画的东西了,画的位置,我们需要在onMeasure中确定画的大小,代码比较简单,如下所示。
接下来就是最重要的怎么画了,当然是在我们的onDraw函数中了。我们先画不支持动画显示的,从简单的开始,我们先画进度部分,由于涉及到渐变,我们需要在起始色和结束色中间获取过渡色,我们调用如下函数即可。
这里可能有小伙伴要说安卓API中就有渐变,比如LinearGradient、SweepGradient、RadialGrdient,不过其局限性比较大,所以我还是选择如上的方式获取渐变色。
我们从起始角startAngle开始画,画到startAngle + progress * unitAngle即可,每次增加1弧度即可,相关代码如下所示。
下图显示了进度为70的进度样子。
画完了进度后,我们把进度相关代码注释掉,现在我们只关心画背景色,背景色我们只需要画能看到部分即可,不需要画进度后面的背景色,这样还提升了绘制效率。由于我们背景色还包含一个中间色,所以还需要区分下左面和右面。相关代码如下所示。
下图显示了进度为30的背景色样子。
好了,我们把进度相关代码取消注释,再运行一遍便可得到最终效果。
下面我们来为其加上动画,所谓动画,就是让其从进度为0开始画,一点点画到progress即可,我们设置一个变量curProgress来表示当前进度,当curProgress < progress时,curProgress自增,再调用postInvalidate()即可,具体完整代码如下所示。
最后我们在布局中如下引用
最终效果如下所示。
结语
这次自定义View的实战讲解还是很具体细致的,希望大家能学到些什么,比如如何一步步分析问题,解决问题的。还有就是能把初始化放在onDraw之外的就都放onDraw外,在onDraw中只做onDraw相关的,还有一些小细节就自己去发现吧。代码已上传GitHub,喜欢的记得star哦。
相关推荐