这次给大家带来的是一篇关于自定义View实现水波动画效果的文章,其实在去年项目中使用过类似的动画,当时就自定义View也实现了预期的效果,最近项目中又使用了相似的效果,于是对代码重新整理了一下并且记录下来,便于以后有类似需求可以当作参考!

按照惯例,无图无真相

image.png

实现方式:

1、正余弦函数实现

2、贝塞尔曲线实现

开篇

看到上边的两种实现方式是不是感觉都和数学公式有关呐,这对于毕业多年之后的我们来说如果当初数学基础不是很好现在估计也全部还给老师了吧,所以一提到相关的数学计算公式只能用一个表情表达了。。。

这TM都是什么.jpg

1、正余弦函数实现

正余弦的函数不知道大家还记不记得,我们温习一下相关参数的意义

y=A*sin(ωx+φ)+k

A—振幅越大,波形在y轴上最大与最小值的差值越大

ω—角速度, 控制正弦周期(单位角度内震动的次数)

φ—初相,反映在坐标系上则为图像的左右移动。这里通过不断改变φ,达到波浪移动效果

k—偏距,反映在坐标系上则为图像的上移或下移。

正余弦函数图.png

我们要实现移动的波形首先是先画出静态的波形,那么怎么来绘制一个波形图呐,Math函数里已经提供了相应的方法,我们可以直接使用

A* Math.sin(ω * x + φ ) + K)

开始绘制之前首先定义相关画笔之类的参数,在此就不做过多说明了,根据上边的公式我们知道需要哪些参数,首先是A,这是振幅,就是波形最高和最低点的差值,我们可以设置定值或者外界传入;其次是ω,角速度,给一个定制或者外界传入;φ,相位,我们就是根据不断改变相位来达到波形移动的效果,每次移动多少可以从外界传入,便于控制速度;K,波形偏移上下的距离,知道了以上各个参数的具体使用意义,下边就可以直接通过代码看下具体实现效果了,毕竟公式都有了,参数也发给你了,剩下的就是根据公式填写以下相应参数就ok了

private void drawSin(Canvas canvas) {

φ -= 0.03;

float y;

path.reset();

path.moveTo(0, getHeight());

for (float x = 0; x <= getWidth(); x += 20) {

y = (float) (A * Math.sin(ω * x + φ ) + K);

path.lineTo(x, getHeight() - y);

}

canvas.drawPath(path, paint);

}

静态的波形图.png

静态的波形出来之后我们就要借助属性动画来让波形动起来

private void initAnimation() {

valueAnimator = ValueAnimator.ofInt(0, getWidth());

valueAnimator.setDuration(1000);

valueAnimator.setRepeatCount(ValueAnimator.INFINITE);

valueAnimator.setInterpolator(new LinearInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

/**

* 刷新页面调取onDraw方法,通过变更φ 达到移动效果

*/

invalidate();

}

});

if (waveStart) {

valueAnimator.start();

}

}

开启动画之后再运行一下看看效果吧

gif录制不流畅,真机效果很好哦.gif

看到这里只是一个单纯的波形,我们一般使用的时候并不是这样的,而是一个封闭的波形,可以向上封闭也可以向下封闭,我们在波形绘制完成之后

.........省略部分代码

//填充矩形

path.lineTo(getWidth(), getHeight());

path.lineTo(0, getHeight());

path.close();

这样就绘制出封闭的波形了,然后画笔设成填充就ok

image.png

代码中我已经对向下密封还是向上密封封装了方法,在此就不再赘述,需要的可以看源码哦,除此之外还有其他的参数都进行了可配置话,可以通过xml进行设置,至此通过正余弦函数进行绘制波形图已经介绍完毕了。

2、贝塞尔曲线实现

对贝塞尔曲线不是很了解的可以自行百度,概念性的东东就不在此赘述,我们使用二阶的贝塞尔进行绘制,为什么选择二阶的呐,看一个图就知道啦

二阶贝塞尔曲线.png

二阶贝塞尔曲线.gif

一段完整的波形其实就是两个二阶的贝塞尔组成的,来看下代码

/**

* sin函数图像的波形

*

* @param canvas

*/

private void drawSinPath(Canvas canvas) {

mWavePath.reset();

mWavePath.moveTo(-mWaveLength + mOffset, mWaveAmplitude);

//相信很多人会疑惑为什么控制点的纵坐标是以下值,

//是根据公式计算出来的,具体计算方法情况文章内容

for (int i = 0; i < mWaveCount; i++) {

//第一个控制点的坐标为(-mWaveLength * 3 / 4,-mWaveAmplitude)

mWavePath.quadTo(-mWaveLength * 3 / 4 + mOffset + i * mWaveLength,

-mWaveAmplitude,

-mWaveLength / 2 + mOffset + i * mWaveLength,

mWaveAmplitude);

//第二个控制点的坐标为(-mWaveLength / 4,3 * mWaveAmplitude)

mWavePath.quadTo(-mWaveLength / 4 + mOffset + i * mWaveLength,

3 * mWaveAmplitude,

mOffset + i * mWaveLength,

mWaveAmplitude);

}

mWavePath.lineTo(getWidth(), getHeight());

mWavePath.lineTo(0, getHeight());

mWavePath.close();

canvas.drawPath(mWavePath, mWavePaint);

}

当时的手绘内容,可能有点乱,只是大致描述一下.png

计算控制点纵坐标的方式.png

根据计算得到起点和控制点坐标之后就可以写代码运行了效果和上边的运行效果一样就不再展示了,上边的计算内容就解释了代码提出的问题

代码中提出的问题.png

3、两种方式对比总结

图像的绘制其实都不复杂,不过关键点还是有几个的。

正余弦函数的波形使用是根据相位控制的,而贝塞尔曲线实现的波形效果是不断改变波的起始位置控制的,并且使用贝塞尔曲线的话需要先在屏幕外边绘制一个完整的波形,保证在平移的过程中可以看到图像不间断的移动来达到移动的波形效果。

最终效果--录制模拟感觉有点卡顿,请真机测试哦.gif

最后

看到这里你是你会感觉到这边文章的内容其实很简单,只要中间的几个点注意一下就可以实现相应的效果了,建议朋友们动手敲一遍代码,加深一下印象,毕竟真是做出来和知道理论没有实践还是有很大区别的!

github源码地址传送门

谨以此篇来记录自己项目中遇到的问题,献给需要类似功能的小伙伴们。如果你有好的建议欢迎评论指出,大家一起讨论、学习、进步!

android 动态波纹效果,Android实用View------水波动画效果多种实现方式详解相关推荐

  1. android 说话水波动画,Android实用View——水波动画效果多种实现方式详解

    原标题:Android实用View--水波动画效果多种实现方式详解 这次给大家带来的是一篇关于自定义View实现水波动画效果的文章,其实在去年项目中使用过类似的动画,当时就自定义View也实现了预期的 ...

  2. android菊花动画,Android实现仿iOS菊花加载圈动画效果

    常见的实现方式 切图,做旋转动画 自定义View,绘制效果 gif图 1.切图会增加体积,但相对简单,不过在换肤的场景下,会使用不同颜色,需要准备多张图,不够灵活. 2.由于自定义的好处,不同颜色只需 ...

  3. Android矢量图动画特效,Android使用SVG矢量图打造酷炫动画效果

    一个真正Android使用SVG矢量图打造酷炫动效往往让人虎躯一震,话不多说,咱们先看看效果: 这个效果我们需要考虑以下几个问题: 1. 这是图片还是文字: 2. 如果是图片该如何拿到图形的边沿线坐标 ...

  4. Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

    Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...

  5. android禁止下拉刷新,Android开发之无痕过渡下拉刷新控件的实现思路详解

    相信大家已经对下拉刷新熟悉得不能再熟悉了,市面上的下拉刷新琳琅满目,然而有很多在我看来略有缺陷,接下来我将说明一下存在的缺陷问题,然后提供一种思路来解决这一缺陷,废话不多说!往下看嘞! 1.市面一些下 ...

  6. Android基础入门教程——8.3.5 Paint API之—— Xfermode与PorterDuff详解(二)

    Android基础入门教程--8.3.5 Paint API之-- Xfermode与PorterDuff详解(二) 标签(空格分隔): Android基础入门教程 本节引言: 上一节,我们学习了Xf ...

  7. Swift教程_零基础学习Swift完整实例(八)_swift完整实例(添加View的动画效果、添加View的阴影)...

    6.添加View的动画效果 本章节主要来做明细页面点击后翻转的动画效果,该效果可以进行多种改变,以达到想要的效果. 1.首先我们需要进行翻转的正反两个view,前面我们已经做好了,分别是PKOElem ...

  8. js动画与html动画效果,九种原生js动画效果

    在做页面中,多数情况下都会遇到页面上做动画效果,我们大部分做动画的时候都是使用框架来做(比如jquery),这里我介绍下如何让通过原生的js来实现像框架一样的动画效果! 1.匀速动画效果说明:匀速动画 ...

  9. android圆形波纹按钮,android自定义View——圆形波纹扫描效果

    蓝牙项目,考虑到后面可能会用到这个扫描的效果,所以参照大神写好的控件,增加了自己需要使用的接口.也顺便巩固一下自定义view中各种零碎的知识点. 需要的效果图 先放一个效果图,点击中心图片开始动画,再 ...

最新文章

  1. Cenos 软件安装
  2. java的循环中try catch的一点小技巧
  3. CLI4 去掉严格模式
  4. Hadoop报错:All specified directories are failed to load.
  5. 02Prism WPF 入门实战 - 建项
  6. 全网最新IDEA项目注释规范设置
  7. openstack 功能_2016年OpenStack的新功能:看一下Newton版本
  8. Android Binder机制简单了解
  9. SQL挂起的解决办法
  10. Glide4.7.1 圆角与centerCrop冲突问题
  11. Ubuntu 20.04 下 MOSEK 9.3 的安装
  12. Bandicam安装
  13. 一图读懂 | 亿美软通富媒体消息助力营销价值提升
  14. word如何取消封面或者目录下方的页码,页码从正文开始
  15. 浅谈屏幕拍摄泄密跟踪的检测技术
  16. 论文阅读(13) 水母游泳过程中的神经机械波共振(2021)
  17. windows下结束进程命令
  18. 计算机电源负载能力差,电脑电源问题:电脑电源负载能力差的原因及解决方法...
  19. 公链、私链、联盟链是什么?
  20. mysql备份教程_Mysql教程-自动备份数据库

热门文章

  1. 11 个很有用但鲜有人知的 Linux 命令
  2. oracle自增主键用途,Oracle主键自增
  3. Linux下Socket相关头文件总结
  4. 【考试记录】Apsara Clouder云计算技能认证:云数据库管理与数据迁移
  5. pdf转换成word在线使用简易教程
  6. np.append()函数用法
  7. MVP框架+Retrofit网络请求
  8. 博途v13入门_博途(TIA PORTAL)V13软件
  9. 关于GitHub上传超过100M上传失败问题
  10. 最新AI创作系统V5.0.2+支持GPT4+支持ai绘画+实时语音识别输入+文章资讯发布功能+用户会员套餐