Android贝塞尔曲线的简单应用之——实现自定义圆形控件内水波纹自动上升效果Demo

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_37717853/article/details/86483838

先上效果:

在这里插入图片描述

gif可能看不到,上两张截图

在这里插入图片描述在这里插入图片描述

贝塞尔曲线知识的简单应用,自定义了个圆形控件,控件内水波纹自动上升,通过几个简单的seekbar做了个简单的颜色选择器。
很早之前就听过说贝塞尔曲线,只是一直没时间好好学习一番,最近忙里偷闲,便想着了解一下,网上关于贝塞尔曲线的解释很多,这里我就暂时不班门弄斧了,如果还不甚了解又有兴趣了解的小伙伴,可以去看看这个作者的博客,其中关于贝塞尔曲线的介绍那篇写的还挺通俗易懂的。

部分关键代码如下:

1.为了控件更灵活易于拓展,自定义一些属性

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="BezierView">
        <!--水位上升动画的执行时间-->
        <attr name="duration1" format="integer"/>
        <!--水波周期移动动画的执行时间-->
        <attr name="duration2" format="integer"/>
        <!--水波高度-->
        <attr name="waveHeight" format="integer"/>
        <!--水波长度-->
        <attr name="waveWidth" format="integer"/>
        <!--初始点Y坐标,即水位初始位置-->
        <attr name="originY" format="integer"/>
        <!--背景圆的颜色-->
        <attr name="cirColor" format="color"/>
        <!--背景圆的轮廓的颜色-->
        <attr name="cirSideColor" format="color"/>
    </declare-styleable>

2.创建自定义view,onDraw中的代码如下:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //画背景圆
    mCanvas.drawCircle(radius,radius,radius,bgCirPaint);
    //不断的计算波浪的路径
    calculatePath();
    //在背景圆上绘制水波
    mCanvas.drawPath(path,paint);
    //将画好的圆绘制到画布上
    canvas.drawBitmap(mbitmap,0,0,null);
    //绘制圆的轮廓(边)
    canvas.drawCircle(radius,radius,radius,cirPaint);
}

3.计算波浪的路径path,这里便用到了贝塞尔曲线来绘制水波纹的路径:

 private void calculatePath() {
    
            //初始点
            
            path.moveTo(-waveWidth + dex, originY - dey);
            
            for (int i = -waveWidth; i < width + waveWidth; i += waveWidth) {
    
                //二阶贝塞尔曲线绘制
                path.rQuadTo(waveWidth / 4, -waveHeight, waveWidth / 2, 0);
                path.rQuadTo(waveWidth / 4, waveHeight, waveWidth / 2, 0);
            }
    
            //绘制连线
            path.lineTo(width, height);
            path.lineTo(0, height);
            path.close();//关闭当前轮廓。如果当前点不等于轮廓的第一个点,则自动添加线段,使其形成闭区间。
        }

4.动画效果部分:水波上升和水波移动效果,都可以通过属性动画来实现,而且实现方式几乎一样,这里是在自定义view内实现一个public的开启动画的方法供activity在适当地时候去调用:

public void startAnimation() {

        //初始化水波效果动画
        animator1 = ValueAnimator.ofFloat(0, 1);//定义一个值从0到1的控制值
        animator1.setDuration(duration2);//水波移动周期时长
        animator1.setRepeatCount(ValueAnimator.INFINITE);//设置循环次数,0为1次,无穷尽的一直执行:ValueAnimator.INFINITE
        animator1.setInterpolator(new LinearInterpolator());//插值器,线性匀速播放动画,不设置其实也是默认匀速
        //监听
        animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //获取属性动画当前值(0-1)
                float fraction = (float) animator1.getAnimatedValue();
                dex = (int) (waveWidth * fraction);//根据动画进行进度,动态修改整条波浪线的长度
                //清空画布
                if (path != null)
                    path.reset();
                //刷新
                postInvalidate();
            }
        });
        //启动动画
        animator1.start();

        //初始化水位上升动画
        animator2 = ValueAnimator.ofFloat(0, 1);//定义一个值从0到1的控制值
        animator2.setDuration(duration1);//水波上升周期时长
        animator2.setRepeatCount(0);//设置循环次数,0为1次,无穷尽的一直执行:ValueAnimator.INFINITE
        animator2.setInterpolator(new LinearInterpolator());//插值器,线性匀速播放动画,不设置其实也是默认匀速
        //监听
        animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //获取属性动画当前值(0-1)
                float fraction = (float) animator2.getAnimatedValue();
                dey = (int) ((height+waveHeight*2) * fraction);//根据动画进度,dey的值会从0慢慢接近于heitht+waveHeight*2的高度
                //清空画布
                if (path != null)
                    path.reset();
                //刷新
                postInvalidate();
            }
        });
        //启动动画
        animator2.start();
    }

关键代码就是上面的这些啦,估计有经验的小伙伴看到这里已经知道怎么做了,要是懒得自己写,可以直接去下我的demo也行,demo中已有详细注释:

Demo下载地址:https://download.csdn.net/download/qq_37717853/10916906

项目参考博客:
1.https://www.cnblogs.com/wjtaigwh/p/6750184.html
2.https://blog.csdn.net/u013087553/article/details/68490170

猜你喜欢

转载自blog.csdn.net/qq_37717853/article/details/86483838