效果图

先上效果图

screenshot.gif

实现

WaveView的属性

WaveView的属性

Wate Level(水位) - 波浪静止时水面距离底部的高度

Amplitude(振幅) - 波浪垂直振动时偏离水面的最大距离

Wave Length(波长) - 一个完整的波浪的水平长度

Wave Shift(偏移) - 波浪相对于初始位置的水平偏移

实现思路

设想我们有一个画好波形的图片,那么我们只需要用这张图片填充(X轴方向重复,Y轴方向延伸)整个View,然后水平移动图片,就可以得到波浪效果了。

所以要做的事很简单:绘制一个波形图,填充到View里,移动波形图。

1. 绘制初始波形

private void createShader() {

...

Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bitmap);

// Draw default waves into the bitmap

// y=Asin(ωx+φ)+h

float waveX1 = 0;

final float wave2Shift = mDefaultWaveLength / 4;

final float endX = getWidth();

final float endY = getHeight();

...

while (waveX1 < endX) {

double wx = waveX1 * mDefaultAngularFrequency;

int startY = (int) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx));

// draw bottom wave with the alpha 40

canvas.drawLine(waveX1, startY, waveX1, endY, wavePaint1);

// draw top wave with the alpha 60

float waveX2 = (waveX1 + wave2Shift) % endX;

canvas.drawLine(waveX2, startY, waveX2, endY, wavePaint2);

waveX1++;

}

// use the bitamp to create the shader

mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);

mViewPaint.setShader(mWaveShader);

}

首先一个长宽恰等于WaveView的Bitmap:Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888)。

在Bitmap中使用默认的属性绘制出初始波形。初始波形的属性:Wate Level(水位)为WaveView高度的1/2;Amplitude(振幅)为WaveView高度的1/20;Wave Length(波长)等于WaveView的宽度。

绘制好的初始波形是下面这个样子:

初始波形

代码第 9 ~ 27 行进行初始波形的绘制。波形由wave1和wave2两个波组成,wave2就是wave1向左偏移1/4的wave length,所以不需要重复计算。

最后把这个Bitmap设置成为Paint的Shader。设置Shader相当于设定画笔的形状,使用设置了Shader的Paint绘制图形时,实际上是在使用Bitmap填充绘制的区域。X轴的填充方式为TileMode.REPEAT,即重复填充;Y轴的填充方式为TileMode.CLAMP,即使用边缘的色值延伸填充。

2. 调整Bitmap的大小并填充到WaveView

有了初始波形,当WaveView的属性改变时,只需要对初始波形进行相应的拉伸/压缩和位移就可以得到用户想要的波形。

// sacle shader according to mWaveLengthRatio and mAmplitudeRatio

// this decides the size(mWaveLengthRatio for width, mAmplitudeRatio for height) of waves

mShaderMatrix.setScale(

mWaveLengthRatio / DEFAULT_WAVE_LENGTH_RATIO,

mAmplitudeRatio / DEFAULT_AMPLITUDE_RATIO,

0,

mDefaultWaterLevel);

// translate shader according to mWaveShiftRatio and mWaterLevelRatio this decides the start position(mWaveShiftRatio for x, mWaterLevelRatio for

// this decides the start position(mWaveShiftRatio for x, mWaterLevelRatio for y) of waves

mShaderMatrix.postTranslate(

mWaveShiftRatio * getWidth(),

(DEFAULT_WATER_LEVEL_RATIO - mWaterLevelRatio) * getHeight());

// assign matrix to invalidate the shader

mWaveShader.setLocalMatrix(mShaderMatrix);

float radius = getWidth() / 2f

- (mBorderPaint == null ? 0f : mBorderPaint.getStrokeWidth());

canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, radius, mViewPaint);

代码 3 ~ 6 行对Shader进行拉伸/压缩,10 ~ 12 行对Shader进行水平/竖直平移。

代码 17 ~ 19 行用Shader填充成想要的形状。

3. 动画

// horizontal animation.

// wave waves infinitely.

ObjectAnimator waveShiftAnim = ObjectAnimator.ofFloat(

mWaveView, "waveShiftRatio", 0f, 1f);

waveShiftAnim.setRepeatCount(ValueAnimator.INFINITE);

waveShiftAnim.setDuration(1000);

waveShiftAnim.setInterpolator(new LinearInterpolator());

animators.add(waveShiftAnim);

// vertical animation.

// water level increases from 0 to center of WaveView

ObjectAnimator waterLevelAnim = ObjectAnimator.ofFloat(

mWaveView, "waterLevelRatio", 0f, 0.5f);

waterLevelAnim.setDuration(10000);

waterLevelAnim.setInterpolator(new DecelerateInterpolator());

animators.add(waterLevelAnim);

// amplitude animation.

// wave grows big then grows small, repeatedly

ObjectAnimator amplitudeAnim = ObjectAnimator.ofFloat(

mWaveView, "amplitudeRatio", 0f, 0.05f);

amplitudeAnim.setRepeatCount(ValueAnimator.INFINITE);

amplitudeAnim.setRepeatMode(ValueAnimator.REVERSE);

amplitudeAnim.setDuration(5000);

amplitudeAnim.setInterpolator(new LinearInterpolator());

animators.add(amplitudeAnim);

代码 3 ~ 8 行让波形一直向右移动,效果就是波形一直在波动。

代码 12 ~ 16 行让水位从0逐渐涨到WaveView高度的一半。

代码 20 ~ 26 行波浪的大小从大变小,再从小变大。

源代码

代码在github:WaveView

打个广告

美团平台及酒旅事业群招人啦,欢迎加入我们!

我可以帮忙内推,简历请发到我邮箱gelitenight@gmail.com

【美团网】高级Android开发工程师

工作内容: 负责美团酒店、旅游产品 Android 客户端的设计、开发与改进。

3年以上工作经验,2年以上Android开发经验;

熟悉Android系统,熟悉Android软件的开发、测试、分发流程;

良好的编程风格,扎实的编程基础和数据结构算法基础;

熟悉移动网络的特性,对网络编程和常用网络协议有较深刻理解和经验;

有一定的架构设计能力,良好的编码能力,编写文档能力;

热爱互联网和新技术,具有极强的快速学习能力;

有以下特征优先考虑:

有开源作品或技术博客(需原创技术文章);

熟悉Socket编程。

北京、上海、厦门、成都都有职位,更多职位请见职位列表。

android录音波浪动画_Android实现波浪效果 - WaveView相关推荐

  1. android录音波浪动画_Android 自定义波浪动画--让进度浪起来~

    waveview <Android 自定义波浪动画之"让进度浪起来~"> 转载请注明来自 傻小孩b_移动开发(http://www.jianshu.com/users/ ...

  2. android录音波浪动画_Android语音输入的波浪效果 – WaveView

    效果展示 源码地址 实现思路 绘制正弦波形 水平移动波形,即可得到破浪效果. 正弦波形的绘制 private void createShader() { ... Bitmap bitmap = Bit ...

  3. android录音波浪动画_Android自定义View实现波浪动画

    本文实例为大家分享了Android自定义View实现波浪动画的具体代码,供大家参考,具体内容如下 效果演示 代码调用与实现效果 xml中调用 android:layout_width="ma ...

  4. android录音波浪动画_Android 自定义 view 实现波浪动画进度条

    最近在做项目时需要实现这样一种动画,类似于波浪形的进度动画,粗略的看了一下,发现好像类似于正余弦曲线实现的,但是Android 没有相关的API,所以需要我们动手画出来,所以现在在此记录一下学习过程, ...

  5. android 同根动画_android 动画系列 (1) - tween 动画(view动画)

    这是我这个系列的目录,有兴趣的可以看下: android 动画系列 - 目录 tween 动画早些时候我们也叫补间动画(我也不知道为啥),现在也有叫 view 动画的.tween动画是2.X 时代的产 ...

  6. android共享元素动画_Android共享元素过渡动画

    android共享元素动画 In this tutorial we'll implement a different kind of animation transition namely Share ...

  7. android录音波浪动画_Android实现炫酷的波浪下载Loading动画

    1. 简介和效果分析 一直都觉得有很多loading动画挺炫酷的,然后自己看过一些之后也想实现一个,加强一下对绘制view的练习,能力有限,很多地方的实现的有欠考虑和逻辑优化,不管怎么样画了两天还是把 ...

  8. android录音波浪动画_Android使用音频信息绘制动态波纹

    在一些音乐类应用中, 经常会展示随着节奏上下起伏的波纹信息, 这些波纹形象地传达了声音信息, 可以提升用户体验, 那么是如何实现的呢? 可以使用Visualizer类获取当前播放的声音信息, 并绘制在 ...

  9. android 环形时间显示_Android自定义波浪加载圆形进度条——(自定义控件 一)...

    自定义控件-- 波浪形状圆形进度加载 时间管理的基础是精力管理,精力的高低.正负分影响到我们的效率 而时间是无法管理的,能够管理的只有自己,透过管理自己的习惯,管理自己的事件来达成对时间的管理. 而在 ...

最新文章

  1. python下载指定的版本包
  2. 【Python】详解Python模块、包、库
  3. java 线程 通过interrupted_分析Java线程中断机制stop和interrupted的用法
  4. boost::type_erasure模块Associated types相关的测试程序
  5. [转]Web3 是去中心化的“骗局”?
  6. P2217-[HAOI2007]分割矩阵【dfs,记忆化搜索】
  7. vue 组件间传值、兄弟组件 、bus方式 ( 1 分钟看懂 )
  8. win7发现不了无线网络怎么办 win7发现不了无线网络的解决办法
  9. Phpcms V9全站伪静态设置方法
  10. su root 后还是不能使用useradd ,useradd 等命令
  11. 经典Java-SpringCloud面试题
  12. H5禁用长按选取,原生拷贝功能
  13. EasyUi之书籍功能(CRUD)
  14. JS:键盘事件(onkeydown 、onkeypress、 onkeyup三个)
  15. 批量将不同文件夹目录中的文件统一提取到同一个文件夹中
  16. 计算机绘图员技师证怎么考,地图制图员》与 《摄影测量员》中级高级工程测量职业标准-如何考-考什么内容...
  17. MT7658芯片组资料,MT7658处理器参数介绍
  18. 洛谷 P1049 装箱问题
  19. 软件产品选型测试/POC测试
  20. C#之Base64编码解码

热门文章

  1. linux系统子接口配置文件,linux配置子接口
  2. 心肺运动试验----各类参数分析笔记
  3. FFmpeg简单使用:音频编码 ---- pcm转aac
  4. 2017年12月。。
  5. Linux的pcie模拟网卡,Intel英特尔PCIe万兆网卡虚拟功能驱动4.11.1版For Linux(2021年3月5日发布)...
  6. 帷幄匠心面试题 一面
  7. 开源项目——寝室助手
  8. 金仓数据库KingbaseES中 ksql常用命令总结
  9. NCE4 L46 Hobbies
  10. vue css 拖拽,vue----拖拽小方块