自定义View贝塞尔曲线-波浪线

这两天呢正在学习自定义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;
    }
}

一些细节上的讲解因为本人也是刚学有些还是不太懂所以就不讲了免得勿扰了大家,其他的朋友可以拿去参考一下,往后有新的理解了会及时补充到上边的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值