需求
因为开发launcher的桌面启动动画的时候,根据设计师的要求,需要实现一个涟漪的效果,具体效果如下:
我Google搜索了一下涟漪效果,发现Github上有一些类似的开源库,但是发现大部分都是点击按钮然后开始出现涟漪效果,与自己要做的这个涟漪动画不太符合,所以在dwl的启发下,想着干脆自己实现一个算了,于是就尝试着自定义这个涟漪动画,最终实现的效果就和上面的是一样的,下面阐述一下实现原理
原理
首先我们将这个动画看成是一个圆环,圆环里面的小圆是一个空心的透明圆,外面是一个透明的大圆,draw圆环的原理很简单,就是在draw透明圆的基础上,将画笔paint的strokeWidth设置成外面的环的宽度
这里需要注意的是,事实上通过设置strokeWidth之后draw出来的外面大圆的半径并不是简单的内圆的半径加上圆环的宽度,而是内圆的半径+1/2圆环的宽度
如下图所示,红色的就是半径就是我们在draw圆环外面大圆的时候应该设置的半径,然后将笔宽strokeWidth设置为圆环的宽度即可:
实现
那么知道draw圆环的原理之后,下面就可以开始draw了,里面的小圆很简单:1
canvas.drawCircle(centerX, centerY, mCircleRadius, mCirclePaint);
外面的大圆:1
canvas.drawCircle(centerX, centerY, mCircleRadius + mRippleWidth / 2, mRipplePaint);
重点就是mRippleWidth这个变量,根据动画介绍可以,波纹的宽度是从0到mRippleWidth,那么根据上面我们说的外圆的半径为内圆的半径+1/2(圆环)波纹的宽度,所以大圆的半径是mCircleRadius+mRippleWidth/2
半径的变化规律知道了,只有半径的变化显然是不够的,为了达到波纹从0到mRippleWidth的效果,我们必须同步更改大圆画笔paint的strokeWidth的值,也就是画出圆环效果,strokeWidth的变化规律和波纹宽度是一样的,从0到mRippleWidth。ok,知道了半径和大圆画笔的变化规律,接下来就是按照规律去改变对应的值,然后刷新界面了,代码如下:
1 | ValueAnimator va = ValueAnimator.ofInt(0, sRippleWidth); |
在初始化代码片段中,我们将外面的大圆画笔paint的strokeWidth初始化为0,颜色初始化成波纹的颜色:1
2
3mRipplePaint.setStyle(Paint.Style.STROKE);
mRipplePaint.setStrokeWidth(0);
mRipplePaint.setARGB(127, 255, 255, 255);
然后根据动画的定义,我们逐渐地将画笔的宽度设置为从0到最终波纹宽度的每一个临时宽度,同时也将波纹变化过程中的的每一个临时宽度值赋值给mRippleWidth用来更新大圆的半径。然后调用invalidata()刷新界面,这样效果就出来了
当然还有一些细节,比如波纹宽度渐变的过程中,要伴随着alpha变化,同时要求波纹到指定时间后自动开始(这里是3000毫秒开始),都需要我们去实现,但这些不是主要难点了,相信大家都能搞定
就这样了,欢迎大家交流意见