安卓自定义控件之仪表盘

安卓自定义控件之仪表盘

目标

今天我们要实现的效果为:

安卓自定义控件之仪表盘

这个一个仪表盘,我们需要设置它的1、圆弧的颜色2、指针的相应的转动。

思路:

简单:我们这个其实比较简单的实现思路就是让UI给我们表盘和指针切图,然后将表盘绘制在canvas上,然后用matrix承载指针,然后根据给定的值让指针滑动转动就好了。

正常:但是今天我们就不要切图了(毕竟没有ui帮我切)。看着效果还是简单,我们就自己绘制好了。

这里主要分几个步骤:

1、      绘制圆弧。

2、      绘制刻度。

3、      绘制指针。

 

实现:

开场习惯

1、      我们将控件的大小和padding的获取放在onSizeChanged里面。

2、      处理padding带来的宽高变化(padding需要自己处理)

3、      画布统一移动到需要的中心点再开始处理

 

控件大小获取

 安卓自定义控件之仪表盘

安卓自定义控件之仪表盘

设定了这几个的半径之后就可以开始绘制了。

在得到了相关数据之后我们就可以开始绘制了。

绘制的步骤:

安卓自定义控件之仪表盘

1、      init:就是讲画布移到中间的位置方便操作,一般移动到中心点,鉴于这次这个是圆这种对称图形,且我们只画一半,我们就不把画布移动到中心点了,且只要一般,我们就移动下。这个习惯是继承自GcsLoop大神(http://www.gcssloop.com/#blog)。

安卓自定义控件之仪表盘

这里我们就垂直移动一个画布高度,向右移动:

安卓自定义控件之仪表盘

2、      绘制圆弧

对于圆弧这种东西,没有专门的函数。因为比较单一,我们就用path来绘制就好了。

安卓自定义控件之仪表盘

安卓自定义控件之仪表盘

3、      绘制刻度

安卓自定义控件之仪表盘

这里很关键的点就是我们通过旋转画布来绘制刻度,这个是比较简单的。

注意:

画布一层一层画布的叠加,当执行canvas.draw之后,我们就算完成了一层画布的绘制。然后就有一个新的画布开始作画。但是很重要的一点是画布给新的了,但是画布的状态是会一直延续的。比如我们移动画布到中心点,以后的画布状态就是中心点在

(getWidth() / 2, getHeight() - mPointRadius - 10)

比如这里我们要旋转画布去画刻度,旋转之后画布的状态是旋转后的状态。也就是反方向的180度。这样就妨碍我们后续的作画。对此,我们需要先保存画布移动前的状态,然后在旋转之后再恢复画布旋转之前的状态。

安卓自定义控件之仪表盘

4、绘制指针

安卓自定义控件之仪表盘


安卓自定义控件之仪表盘

这里我们指针和效果图略有不同,我们画直线的时候直接画的是与圆的切线。这样比较简单嘛。转动角度的话我们还是通过旋转画布来实现。

这里是ondraw的最后一步。

到目前为止,我们就可以通过设置currentDegree来对指针进行为止设定了。

为了让指针旋转不太生硬,我们这里加入一个插值动画,让指针平滑地滑动到对应的角度:

安卓自定义控件之仪表盘

然后把设置角度和arc颜色的方法暴露出去:

安卓自定义控件之仪表盘

到现在就大功告成了。

 

需要注意的知识点:

1、      invalidate之后的整个画布都是新画布。以前画布的图案,和画布的状态全部重置。

2、      在对画布状体进行改变之前为了不影响后续绘制,都要save下。绘制玩再restore。

3、      那个绘制指针的时候,我设置了path.close。让path封闭的,然后封闭的结果是:

安卓自定义控件之仪表盘

(mac没有下画图工具~将就看了)。