现在的互联网真是浪啊,那么多app上使用会动的波浪效果,就像下面这幅图一样:
浪呀么浪
这样的效果其实也是也是通过Path实现的,老样子,既然是自定义view还是要初始化画笔,这里不再多说:
private void initPaint() {
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(mLineWidth);
}
首先,我们要了解波浪是怎么画出来的,这里涉及到Path的两个方法:rQuadTo和quadTo,那这两个方法有什么区别呢?rQuadTo的四个参数分别是曲线控制点的坐标和终点的横纵坐标,这里的坐标是相对上一个终点(这里需要注意,不是相对于控制点)而言的,而quadTo是绝对坐标,两者具体的区别不在这里叙述。
首先我们在onDraw方法中画出第一个波浪:
mPath1.moveTo(0, getHeight() * 0.2f);
mPath1.rQuadTo(getWidth() * 0.25f, -getHeight() * 0.025f, getWidth() * 0.5f, 0);
mPath1.rQuadTo(getWidth() * 0.25f, getHeight() * 0.025f, getWidth() * 0.5f, 0);
注意,这里的坐标是相对的,尽管有些点的坐标一样,但他们不是一个点。接着我们画出第二个波浪,只需要将两个控制点的y坐标取负值即可取出和第一个波浪相反的波浪:
波浪画好后要怎样让他们浪起来呢?不得不说其实自定义View好多东西都是视觉欺骗,难道曲线真的和波浪一样会上下起伏吗?并不是,如果你仔细盯着曲线上的一个点移动的话,就会发现这只不过是曲线在向右平移罢了。既然要平移,就必须有的移,所以我们将Path的起始点移动到屏幕之外的一个点,当然最好初始值也是屏幕的宽度:
mPath1.moveTo(-getWidth() + count * getWidth(), getHeight() * 0.2f);
mPath2.moveTo(-getWidth() + count * getWidth(), getHeight() * 0.2f);
for (int i = 0; i < 2; i++) {
mPath1.rQuadTo(getWidth() * 0.25f, -getHeight() * 0.025f, getWidth() * 0.5f, 0);
mPath1.rQuadTo(getWidth() * 0.25f, getHeight() * 0.025f, getWidth() * 0.5f, 0);
mPath2.rQuadTo(getWidth() * 0.25f, getHeight() * 0.025f, getWidth() * 0.5f, 0);
mPath2.rQuadTo(getWidth() * 0.25f, -getHeight() * 0.025f, getWidth() * 0.5f, 0);
}
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(3000);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.start();
valueAnimator.addUpdateListener(animation -> {
count = (float) animation.getAnimatedValue();
invalidate();
});
这里的count是属性动画获取的渐变值,count不断增大,path的起始点就会不断向右,所以就形成了移动的效果,那为什么要循环一次呢,这是因为开始的时候count是0,屏幕中是没有东西的,为了在动画执行过程中显示出完整的波浪,所以需要画出两个周期的波形,也就是说,波形其实一共是屏幕和屏幕左侧两个周期,然后在将初始点移动。这里需要注意的是需要给动画设置valueAnimator.setInterpolator(new LinearInterpolator()),因为valueAnimator默认不是匀速的,在开始和结束的时候会逐渐变慢直到停止,所以当动画执行下一次时会有一个顿挫感,就好像踩离合时突然抬脚一样,设置线性插值器后,波浪就是非常自然了!