- 怎样画波浪
通过贝塞尔曲线
- 怎样让波,浪起来
让波浪水平移动
- 保持让波浪动起来时,一直正确显示波浪
确保左侧起点始终小于0,
//使用
final WaveView viewById = (WaveView) findViewById(R.id.bezier);
viewById.post(new Runnable() {
@Override
public void run() {
viewById.start();
}
});
实现思路
- 用
Path
配合rQuadTo
画出单个波浪的区域 - 画出所有波浪,并且在控件不可视的范围处(x < 0)处也添加上一个波浪
- 通过
ValueAnimator
不断修改Path
的左侧起始位置dx
,并且触发重绘,ValueAnimator
的取值范围是负单个波浪宽度 - 0
是为了确保动画不会出现奇怪的位移
package com.example.a18.path.wave;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
/**
* desc: todo 描述本类功能
* author: pdog
* email: pdog@qq.com
* time: 2017/11/8 12 :34
*/
public class WaveView extends View {
private Paint mPaint;
private Path mPath;
private int mWidth;
private int mHeight;
public WaveView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
//当前移动的距离
float tranlateWidth;
ValueAnimator mValueAnimator;
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(2);
mPath = new Path();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mValueAnimator = ValueAnimator.ofInt(0,1);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
tranlateWidth = valueAnimator.getAnimatedFraction() * mWidth;
invalidate();
System.out.println("update...");
}
});
mValueAnimator.setDuration(1 << 10);
mValueAnimator.setInterpolator(new LinearInterpolator());
mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
mValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mValueAnimator.cancel();
mValueAnimator = null;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = getWidth();
mHeight = getHeight();
float waveHeight = (float) (mWidth / 5);
mPath.moveTo(-mWidth, 0);
mPath.rCubicTo(mWidth / 4 * 1, -waveHeight, mWidth / 4 * 3, waveHeight, mWidth, 0);
mPath.rCubicTo(mWidth / 4 * 1, -waveHeight, mWidth / 4 * 3, waveHeight, mWidth, 0);
mPath.rLineTo(0, mHeight >> 1);
mPath.rLineTo(-mWidth << 1, 0);
mPath.close();
}
public void start() {
mValueAnimator.start();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(tranlateWidth, getHeight() >> 1);
canvas.drawPath(mPath, mPaint);
}
}