[Java] 查看源文件 复制代码
wavePaint.setColor(mBehindWaveColor);[/font] for (int beginX = 0; beginX < endX; beginX++) {
double wx = beginX * mDefaultAngularFrequency;
float beginY = (float) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx));
canvas.drawLine(beginX, beginY, beginX, -1, wavePaint);
waveY[beginX] = beginY;
}
wavePaint.setColor(mFrontWaveColor);
final int wave2Shift = (int) (mDefaultWaveLength / 4);
for (int beginX = 0; beginX < endX; beginX++) {
canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, -1, wavePaint);
}
2、在HeaderWaveView中提供get方法返回sin函数的height
[Java] 查看源文件 复制代码
public float getSinHeight() {
//sin函数的height
return (float) (getHeight() * mWaterLevelRatio
+ mAmplitudeRatio / DEFAULT_AMPLITUDE_RATIO * mDefaultAmplitude * Math.sin(mWaveShiftRatio * getWidth() * mDefaultAngularFrequency));
}
动画实现创建HeaderWaveHelper类进行动画管理,动画采用AnimatorSet进行组合。通过设置waterLevelRatio波浪水位、amplitudeRatio波浪振幅、mDefaultFloatViewRotation头像旋转调整角,调整整个效果。
当动画cancel时,不能很鬼畜的直接将振幅调零,start时也同理,应该缓慢过渡。
[Java] 查看源文件 复制代码
public void cancel() {
if (mAnimatorSet != null && !mHasCancel) {
mHasCancel = true;
mHasStart = false;
mAmplitudeAnim.cancel();
amplitudeChangeAnim = ObjectAnimator.ofFloat(
mHeaderWaveView, "amplitudeRatio", mDefaultAmplitudeRatioT, 0.00001f);
amplitudeChangeAnim.setDuration(1000);
amplitudeChangeAnim.start();
amplitudeChangeAnim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
if (mFloatView.getAnimation() != null) {
mFloatView.getAnimation().cancel();
}
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
}
}
public void start() {
mHeaderWaveView.setShowWave(true);
if (mAnimatorSet != null && !mHasStart) {
mHasStart = true;
mHasCancel = false;
if (amplitudeChangeAnim != null) {
amplitudeChangeAnim = ObjectAnimator.ofFloat(
mHeaderWaveView, "amplitudeRatio", 0.00001f, mDefaultAmplitudeRatioF);
amplitudeChangeAnim.setDuration(1000);
amplitudeChangeAnim.start();
}
if (!mIsFirst) {
mAnimatorSet.start();
mIsFirst = true;
}
}
}
三个动画A、B、C组合成一个AnimatorSet,playTogether,其中A、B是循环的,而C需要实现三个阶段,从0到0.5的过渡(单次),0.5-0.8的来回(循环),停止时再由当前循环数值到0(单次)。我的实现思路是,由A、B、C的循环构成AnimatorSet,在停止事件触发后cancel C的动画,然后new一个动画实现C的当前数值到0,开始同理。而整个结束开始过程中AnimatorSet一直运行。老是感觉这种动画实现方法不优雅,不知道有没有其他更好的实现方式。
还有一个小细节,view如果是在onCreat中获取,是无法获得view.getHeight(),采用view.getMeasuredHeight()代替,不理解可以去看看View的绘制机制。
[Java] 查看源文件 复制代码
waveShiftAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//获取sin函数的height,更新mFloatView
float value = mHeaderWaveView.getSinHeight() - mFloatView.getMeasuredHeight();
mFloatView.setRotation(value + mDefaultFloatViewRotation);
mFloatView.setTranslationY(value);
mFloatView.invalidate();
}
});