- 怎樣畫波浪
通過貝塞爾曲線
- 怎樣讓波,浪起來
讓波浪水平移動(dòng)
- 保持讓波浪動(dòng)起來時(shí),一直正確顯示波浪
確保左側(cè)起點(diǎn)始終小于0医咨,
//使用
final WaveView viewById = (WaveView) findViewById(R.id.bezier);
viewById.post(new Runnable() {
@Override
public void run() {
viewById.start();
}
});
實(shí)現(xiàn)思路
- 用
Path
配合rQuadTo
畫出單個(gè)波浪的區(qū)域 - 畫出所有波浪,并且在控件不可視的范圍處(x < 0)處也添加上一個(gè)波浪
- 通過
ValueAnimator
不斷修改Path
的左側(cè)起始位置dx
,并且觸發(fā)重繪,ValueAnimator
的取值范圍是負(fù)單個(gè)波浪寬度 - 0
是為了確保動(dòng)畫不會(huì)出現(xiàn)奇怪的位移
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();
}
//當(dāng)前移動(dòng)的距離
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);
}
}