最近做了一个项目,项目中有这么一个需求就是就实现水波纹的效果,不仅仅是这样就完事了,在水波纹的情况下它的上方还会有一个头像随着水波纹的效果而动。
package com.example.mickc.customview;
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;
/**
* Created by mickc on 2018/7/12.
*/
public class WaveLine extends View {
private Paint paint1;
private Path path1;
private Paint paint;
private Path path;
private float φ;
public WaveLine(Context context) {
super(context);
initView();
}
public WaveLine(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public WaveLine(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
//初始化画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setAntiAlias(true);//消除锯齿
paint.setStyle(Paint.Style.FILL);
//初始化path
path=new Path();
paint1 = new Paint();
paint1.setColor(Color.WHITE);
paint1.setAntiAlias(true);
paint1.setStyle(Paint.Style.FILL);
paint1.setAlpha(80);
path1 = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
path1.reset();
float y;
float y1;
//定义path的起点
path.moveTo(getLeft(),getBottom());
path1.moveTo(getLeft(),getBottom());
/**
* y=Asin(ωx+φ)+k
* A—振幅越大,波形在y轴上最大与最小值的差值越大
* ω—角速度, 控制正弦周期(单位角度内震动的次数)
* φ—初相,反映在坐标系上则为图像的左右移动。这里通过不断改变φ,达到波浪移动效果
* k—偏距,反映在坐标系上则为图像的上移或下移。
*/
//让每次震动的时候自减45°
φ -= 0.1f;//从45度位置开始震动
//获取角速度
double ω=2*Math.PI/getWidth();
//根据父view的宽度来设置我们的波浪线的最大宽度
for (int x = 0; x <getWidth() ; x+=20) {
// y2 = (float) (rangeY * Math.sin(ω * x + φ));
//获取曲线 上的每个点
y= (float) (8*Math.sin(ω*x+ φ));
y1 = (float) (8*Math.cos(w*i+φ)+8);
//吧曲线上的每个点用path链接起来
path.lineTo(x,y);
path1.lineTo(x,y1);
//设置个监听给我们的头像使用波浪起伏的y坐标
animationListener.getY(y);
}
//设置path的终点
path.lineTo(getRight(),getBottom());
path1.lineTo(getRight(),getBottom());
//在画板上吧曲线画出来
canvas.drawPath(path,paint);
canvas.drawPath(path1,paint1);
//调用延迟刷新的方法来刷新我们的曲线
postInvalidateDelayed(20);
}
public void setAni(AnimationListener animationListener) {
this.animationListener = animationListener;
}
private AnimationListener animationListener;
public interface AnimationListener {
void getY(float y);
}
}
private void initView() {
wave_view1 = (WaveLine) findViewById(R.id.wave_view1);
image = (ImageView) findViewById(R.id.image);
final FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(-2,-2);
layoutParams.gravity= Gravity.CENTER;
wave_view1.setAni(new WaveLine.AnimationListener() {
@Override
public void getY(float y) {
//用来设置iamge的位置 注意这里的y值是随着波浪起伏的值变化的是个变量
layoutParams.setMargins(0,-200,0, (int) y+2);
//这里吧设置好的参数赋值给我们的image
image.setLayoutParams(layoutParams);
}
}
);
}