一般情况下,波纹效果都是由给定资源配合动画组合而成的。
从一个小圆圈将资源放大结束再重复就形成一条波纹,间隔时间播放六条动画就有了六条波纹。基本的的波纹实现就是这样子的。
但是这样有个缺点就是资源在放大过程中会变得模糊。至于为什么模糊不是本文重点就不详述,不知道的就请先自己看下动画的原理吧。
本文是做出来的波纹效果本质是一个控件在不断描绘。原理就好像一群小孩赛跑,跑得一样快,启示位置差多远就一直差多远,永远也追不上。有灵感的时候想的就是这个,这个比喻好差劲。。。
首先,控件要继承于View.
public class WaveRipView extends View
其次,在oncreate中初始化画笔:
cirRadius = (int) Utils.dip2px(getContext(), 180*3);//,(int) Utils.dip2px(mActivity, 64)180*7;
circlePaint = new Paint();
circlePaint.setColor(Color.rgb(0x5e, 0x8b, 0xff));
circlePaint.setStyle(Style.STROKE);
circlePaint.setAntiAlias(true);
circlePaint.setAlpha(50);
circlePaint.setStrokeWidth((float) 10.0);
3,
重绘时在ondraw中进行绘制。mCount[6]就是赛跑的六个小孩也就是六条波纹。radius是起点半径。f2是波纹离开起点的位置,加上半径就是波纹的半径。
protected void onDraw(Canvas canvas) {
setBackgroundColor(Color.TRANSPARENT);
int height = getHeight();
int width = getWidth();
//angle++;
// 最小半径
int radius = 1 * cirRadius / 15;
// 最多能扩大多少
float f1 = 8 * cirRadius / 1800;
float f2 = 0;
for (int i = 0; i < mCount.length; i++) {
if(mCount[i]>0){
// 计算百分比距离
f2 = f1 * mCount[i] / 18.0F;
// 扩散光圈效果
canvas.drawCircle(width / 2, height / 2, radius+f2, circlePaint);
}
}
}
4,这六个小孩怎么赛跑的呢?
用handle来进行循环,收到消息MSG_STOP即0时,就让小孩都回家(清零)
收到MSG_INIT(1)就等间隔初始化位置。这里总赛程为1800,6个小孩所以每300米设置一个小孩的起点。
收到MSG_START时就做三件事:1,让每个小孩向前跑X米,X的大小会直接影响波纹的闪动频率;2,无效化视图invalidate,这将会重绘视图,从而将小孩跑了X米的视图显示出来;3,重新发送MSG_START,从而周而复始的循环。最终小孩跑步的整个视图就描绘出来了。想象一下动画进入人眼不也是一个个连续的图么?对了这就是波纹动画了。
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if(msg.what == 0){
mCount[0]=0;
mCount[1]=0;
mCount[2]=0;
mCount[3]=0;
mCount[4]=0;
mCount[5]=0;
invalidate();
}else
if(msg.what == 1){
mCount[0]=1;
mCount[1]=301;
mCount[2]=601;
mCount[3]=901;
mCount[4]=1201;
mCount[5]=1501;
} else{
if(isStart){
for (int i = 0; i < mCount.length; i++) {
if(mCount[i]>1800){
mCount[i]=1;
}else
if (mCount[i]>0) {
mCount[i]+=6;
}
}
invalidate();
handler.sendEmptyMessageDelayed(7, 10);
}
}
};
};
最后,怎么控制波纹重绘与否呢?看到isStart了么?
直接代码了:
public void endAni(){
isStart=false;
handler.sendEmptyMessage(0);
}
public void startAni(){
isStart=true;
handler.sendEmptyMessage(1);
handler.sendEmptyMessageDelayed(7, 10);
}
有什么不对的地方欢迎讨论哈~