这两天呢正在学习自定义view贝塞尔曲线,既然学习了那肯定也是要跟着简单的做出个demo出来,下边不多说先看效果图
因为录制的有问题所以就在网上找了张图
下面贴出代码
package com.bw.system.widget;
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.graphics.PointF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
/**
* @auther: wen
* @time: 2020/3/9 17:39
* @description: 绘制波浪线
* @modifier:
* @updatedata:
*/
public class Bezier2 extends View {
private int width = 0;
private int height = 0;
private int baseLine = 0;// 基线,用于控制水位上涨的,这里是写死了没动,你可以不断的设置改变。
private Paint mPaint;
private int waveHeight = 100;// 波浪的最高度
private int waveWidth;//波长
private float offset = 0f;//偏移量
public Bezier2(Context context) {
super(context);
}
public Bezier2(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public Bezier2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 初始画笔
*/
private void initView() {
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
width = getMeasuredWidth();//获取屏幕宽度
height = getMeasuredHeight();//获取屏幕高度
waveWidth = width;
baseLine = height / 2;
updateXControl();
}
private void updateXControl() {
//设置一个波长的偏移
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, waveWidth);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
offset = value;//不断设置偏移,并重画
postInvalidate();
}
});
valueAnimator.setDuration(1000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(getPath(), mPaint);
}
/**
* 计算path路径
*
* @return
*/
private Path getPath() {
int halfWidth = waveWidth / 2;//一半的波长
Path path = new Path();
path.moveTo(-halfWidth * 3, baseLine);//移动到要绘制的坐标起点
//核心代码
for (int i = -3; i < 2; i++) {
int startX = i * halfWidth;
path.quadTo(startX + halfWidth / 2 + offset,//起始点x
getWaveHeight(i),//控制点y
startX + halfWidth + offset,//结束点x
baseLine//结束点y
);
}
//形成一个封闭的区间
path.lineTo(width, height);//两个不可以调换调换会出现一个交叉的水波纹中间有空白
path.lineTo(0, height);//当然你也可以把这三个都给注释掉看下结果,毕竟自己亲眼看到后才能够知道为什么要这样做
path.close();
return path;
}
private int getWaveHeight(int i) {
if (i % 2 == 0) {
return baseLine + waveHeight;
}
return baseLine - waveHeight;
}
}
一些细节上的讲解因为本人也是刚学有些还是不太懂所以就不讲了免得勿扰了大家,其他的朋友可以拿去参考一下,往后有新的理解了会及时补充到上边的。