Android 实现水波纹效果

最近做了一个项目,项目中有这么一个需求就是就实现水波纹的效果,不仅仅是这样就完事了,在水波纹的情况下它的上方还会有一个头像随着水波纹的效果而动。


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);


                              }
                          }
        );




    }

猜你喜欢

转载自blog.csdn.net/zeyu_rensheng/article/details/81022545