一、前言

这个自定义控件并不是我写的,而是Github上的一个开源控件。
实现方式非常的巧妙,涉及到的知识也比较多点。现在我就来和大家分析一下实现原理。
https://github.com/gelitenight/WaveView

这是我重写了一遍的,加深理解。

二、实现原理

这里涉及到了 Shader,Matrix图像变换矩阵,ObjectAnimator属性动画。
通过给画笔Paint设置BitmapShader,画到画布上。
然后通过矩阵改变Shader的位置和缩放,具体改变的值则交给属性动画处理。

首先我们要创建这么一个Bitmap

  1. 这是两个正弦曲线作为顶边的图形,粉红色是正弦曲线偏移后的结果。
  2. 正弦曲线一个周期的宽度正好是控件的宽度。

那么具体怎么画出这个Bitmap呢?
我们知道正弦曲线的公式为:y=Asin(ωx+φ)+k
A:振幅,控制曲线的起伏高度
ω:周期or频率,控制一个周期的宽度
φ:相位,控制曲线在X轴的偏移
k :控制曲线在Y轴的偏移

我们可以通过Path对象来画出这么个路径,然后drawPath即可。
背面的粉红色也一样,通过相位偏移控件4分之1的宽度。
最后创建BitmapShader设置到画笔即可。

代码如下:

 @Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);createShader();}private void createShader() {int height = getHeight();int width = getWidth();// ω周期  让一个周期的宽度正好是widthdouble frequency = 2 * Math.PI / width;// A振幅  默认的振幅是高度的0.05ffloat amplitude = height * DEFAULT_AMPLITUDE_RATIO;// k(y轴偏移量,进度) 默认的进度是50%float level = height * DEFAULT_LEVEL_RATIO;Bitmap waveBitmap = Bitmap.createBitmap(getWidth(),getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(waveBitmap);Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setStyle(Paint.Style.FILL);Path abovePath = new Path();Path behindPath = new Path();abovePath.moveTo(0, height);behindPath.moveTo(0, height);for(int x = 0; x<=width; x++) {// y=Asin(ωx+φ)+kfloat aboveY = (float) (amplitude * Math.sin(frequency * x))+ level;// 背面的水波偏移一些,和前面的错开。float behindY = (float) (amplitude * Math.sin(frequency * x + width/4*frequency))+ level;abovePath.lineTo(x, aboveY);behindPath.lineTo(x, behindY);}abovePath.lineTo(width + 1, height);behindPath.lineTo(width + 1, height);paint.setColor(mBehindColor);canvas.drawPath(behindPath, paint);paint.setColor(mAboveColor);canvas.drawPath(abovePath, paint);mShader = new BitmapShader(waveBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setShader(mShader);}

这样就可以看到水波了,但是这水波并不会动!

让水波动起来!
首先我们需要使用矩阵,平移Shader

 // 位移的比例(相对于控件宽度),默认1.0f没有位移。private float mWaveTranslateRatio = 1.0f;private Matrix mShaderMatrix = new Matrix();/*** 提供set方法供属性动画使用。* @param waveTranslateRatio*/public void setWaveTranslateRatio(float waveTranslateRatio) {if(mWaveAmplitudeRatio != waveTranslateRatio && waveTranslateRatio >0) {this.mWaveTranslateRatio = waveTranslateRatio;invalidate();}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mShaderMatrix.setTranslate(mWaveTranslateRatio * getWidth(),1f); canvas.drawCircle(getWidth()/2f,getHeight()/2f,getWidth()/2f,borderWidth,mPaint);}

这样就画出一个水波圆形进度条了。但还是不会动,别急。
我们还需要给控件设置属性动画,让水波动起来。
在Activity中代码如下:

WaveView wave = (WaveView) findViewById(R.id.wave);
ObjectAnimator translate = ObjectAnimator.ofFloat(wave,"waveTranslateRatio",0f,1f);
translate.setRepeatCount(ValueAnimator.INFINITE);
translate.setInterpolator(new LinearInterpolator());
translate.setDuration(1000);
translate.start();

这样就完成一个简单的圆形水波进度条了,不过还不能设置进度,也不够炫酷。

想继续了解的可以去Github上下载代码自己研究,也可以研究我的代码,都差不多。只是我精简了一些功能,并且加上了注释。
http://download.csdn.net/detail/u010386612/9445271

三、写在后面

新的一年,祝大家在这一年里身体健康,万事如意。

Android,水波进度条相关推荐

  1. Android中进度条控件使用

    android中进度条控件使用 ProgressBar pb = findViewById(R.id.pb);pb.setMax(100);pb.setProgress(33); 转载于:https: ...

  2. android 自定义 进度条 旋转,Android_Android ProgressBar进度条使用详解,ProgressBar进度条,分为旋转进 - phpStudy...

    Android ProgressBar进度条使用详解 ProgressBar进度条,分为旋转进度条和水平进度条,进度条的样式根据需要自定义,之前一直不明白进度条如何在实际项目中使用,网上演示进度条的案 ...

  3. android中进度条的使用,android的进度条使用

    android的进度条 1.实现的效果 2.布局代码 先写一个my_browser.xml文件 存放WebView android:layout_width="fill_parent&quo ...

  4. android音乐进度条设计代码,【Android】Android开发实现进度条效果,SeekBar的简单使用。音量,音乐播放进度,视频播放进度等...

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先给大家看一下我们今天这个最终实现 ...

  5. android自定义进度条_Android中的自定义进度栏

    android自定义进度条 Custom progress bar in android application gives it a personal touch. In this tutorial ...

  6. Android反向进度条(ProgressBar)的实现——从右到左的进度条

    Android反向进度条(ProgressBar)--从右到左的进度条 前言: 最近在项目中需要使用到反向进度条,在网上查了些资料,感觉对自己作用不大,于是自定义样式,实现了反向进度条. 1. 第一步 ...

  7. android 动态改变进度条,Android条纹进度条的实现(调整view宽度仿进度条)

    Android条纹进度条的实现(调整view宽度仿进度条) 发布时间:2020-10-03 16:14:24 来源:脚本之家 阅读:89 作者:RustFisher 前言 本文主要给大家介绍了关于An ...

  8. Qml水波进度条、扇形进度条等其他进度条

    前言 分割线 正文 横线进度条 水波进度条 扇形进度条 前言 因为需求所致,需要采用进度条,开始采用的是普通的横线进度条,感觉效果也不错,后面改成了水波进度条,也就是好看了一点,在后面改成了扇形进度条 ...

  9. android自定义圆角进度条,Android自定义进度条的圆角横向进度条实例详解

    1.本文将向你介绍自定义进度条的写法,比较简单,但还是有些知识点是需要注意的: invalidate()方法 RectF方法的应用 onMeasure方法的应用 2.原理 画3层圆角矩形,底层为黑色, ...

最新文章

  1. linxu 下安装mysql5.7.19
  2. ---Pcie基本概念普及(扫盲篇--巨适合新手)
  3. 2020人工神经网络第一次作业-参考答案第三部分
  4. jq修改iframe html代码,使用jQuery替换iframe的所有内容(包括doctype和html标签)
  5. python pip全称_Python pip 安装与使用
  6. java数字格式化_Java数字格式
  7. python color属性_使用Python制作一个带GUI界面的词云自动生成工具(连载七)
  8. extern、static
  9. 经典排序算法之基数排序(C语言版)
  10. 无法解析的外部符号+_mysql_fetch_row_vs连接mysql出现以下错误,求解答,谢谢,不胜感激...
  11. vs2012+wdk8.0 搭建wdf驱动开发环境
  12. jquery 操作 input显示或者隐藏
  13. NameError: name 'reload' is not defined等python版本问题解决方案
  14. 单点登录实现机制:web-sso
  15. Spring框架的本质:2Spring IoC其实很简单
  16. C汇编语言是符号化的机器语言,汇编语言
  17. EM算法原理解释及公式推导
  18. 如何将Excel的单元格设置成下拉选项?-excel设置下拉菜单
  19. 自动回复html模板邮件,outlook邮件自动回复设置
  20. android开发中TabHost使用方法

热门文章

  1. 计算机网络周宏博课后题答案,关于计算机硬件组装与教学方法初探.doc
  2. html复选框全选怎么实现,js html css实现复选框全选与反选
  3. ubuntu18.04 realsense
  4. 天气预报API接口整理
  5. 安装rabbitMq报错:error: unpacking of archive failed on file /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.9
  6. Tomcat 集群搭建入门
  7. 1024. 视频拼接 的两种解法
  8. 公共教室计算机安全调查报告论文,东风中学现代教育技术应用调查报告毕业论文...
  9. java从入门到入土图_Java从入门到入土day08
  10. 树莓派--搭建nextcloud私有云