WaveView

Github Repository and libaray

https://github.com/onlynight/WaveView

首先看下演示demo

demo中可以看到不同高度,不同速度,不同幅度的水波纹;你可以通过view的参数直接控制view的表现形式。

引入你的工程

  1. 在项目的根目录下的build.gradle文件中添加如下代码:
allprojects {repositories {...maven { url 'https://jitpack.io' }}
}
  1. 在你需要引用的module中添加如下依赖:
dependencies {compile 'com.github.onlynight:WaveView:1.0.0'
}

使用

布局文件中添加view:

<com.github.onlynight.waveview.WaveView
    android:id="@+id/waveView1"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"app:isCircle="false"app:period="4"app:waveHeightPercent="0.5"app:waveRange="15dp"app:waveSpeed="10"app:waveStrokeWidth="3dp"/>

activity中需要手动启动水波纹

mWaveView1 = (WaveView) findViewById(R.id.waveView1);// when you want start wave you should call WaveView#start() method.
mWaveView1.start();// when you want stop wave you should call WaveView#stop() method.
mWaveView1.stop();

View 属性说明


<declare-styleable name="WaveView"><!-- define wave speed, example value 10 --><attr name="waveSpeed" format="float"/><!-- define wave range, example value 15dp --><attr name="waveRange" format="dimension|reference"/><!-- define wave 1 color --><attr name="wave1Color" format="color|reference"/><!-- define wave 2 color --><attr name="wave2Color" format="color|reference"/><!-- define wave height percent, the value is between 0 to 1 --><attr name="waveHeightPercent" format="float"/><!-- define paint stroke width, if you want optimizing view,you should change the stroke width more--><attr name="waveStrokeWidth" format="dimension|reference"/><!-- if the view is circle --><attr name="isCircle" format="boolean"/><!-- the sine wave period, value range 0 to all --><attr name="period" format="float"/></declare-styleable>

实现原理

我们视觉上看到的是水波纹,实际上只是一个正弦波和余弦波向左位移,然后将三角函数的周期加长,在一个view中不显示整个三角函数的的波形,这样从视觉上来说就是水波纹效果啦。

根据上面的分析,我们知道我们需要计算一个正弦波和一个余弦波,并且根据时间的推移将正弦波或者余弦波向左或者向右平移,最后每次计算完波形图的时候绘制下来就完成啦。下面我们来看下WaveView中的关键代码:

private void drawWave(Canvas canvas, int width, int height) {setPaint();double lineX = 0;double lineY1 = 0;double lineY2 = 0;for (int i = 0; i < width; i += mStrokeWidth) {lineX = i;if (mIsRunning) {lineY1 = mWaveRange * Math.sin((mAngle + i) * Math.PI / 180 / mPeriod) +height * (1 - mWaveHeightPercent);lineY2 = mWaveRange * Math.cos((mAngle + i) * Math.PI / 180 / mPeriod) +height * (1 - mWaveHeightPercent);} else {lineY1 = 0;lineY2 = 0;}canvas.drawLine((int) lineX, (int) lineY1,(int) lineX + 1, height, mWavePaint1);canvas.drawLine((int) lineX, (int) lineY2,(int) lineX + 1, height, mWavePaint2);}
}

可以看到,这里没有选择path进行绘制,因为path绘制无法满足需求,这里通过画竖线;计算每个点起始的位置,然后从这个点画一条线到view的底部,然后循环多次直到view的边界处结束绘制,这样就看到正弦波啦;这时候在每次绘制过程中给三角函数添加一个偏移量,这样每次计算的时候波形就会偏移;最后就完成啦。

有个地方有个坑需要注意,这里可以设置view为圆形;常规的思路是画完以后再将其切成一个圆形,我尝试了各种方法证明这种思路有问题;最后发现需要先限定canvas的绘制区域,然后再将图形绘制到view上去,这样才能实现clip的效果。

@Override
protected void onDraw(Canvas canvas) {super.onDraw(canvas);if (mIsRunning) {int height = getHeight();int width = getWidth();// 这里要注意执行的顺序clipContainer(canvas, width, height);drawWave(canvas, width, height);}
}private void clipContainer(Canvas canvas, int width, int height) {if (mIsCircle) {mContainerPath.reset();canvas.clipPath(mContainerPath);mContainerPath.addCircle(width / 2, height / 2, width / 2, Path.Direction.CCW);canvas.clipPath(mContainerPath, Region.Op.REPLACE);}
}

android自定义WaveView水波纹控件相关推荐

  1. android开发控件水波纹,Android实现水波纹控件的方法

    有很多app使用过水波纹的这样的效果,看着很酷酷的样子,所以自己就撸码写了一个. 实现思路: 利用贝塞尔曲线绘制圆弧(也就是水波的波纹) 通过动画改变绘制的起始点使水波纹平移 首先,定义我们需要的自定 ...

  2. Android自定义一个播放器控件

    介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了.在写VideoView播放视频时候定义控制的代码全写在Actv ...

  3. Android 自定义日期段选择控件,开始日期-结束日期。

    开发中碰到个需求,需要在一个控件中选择完成开始和结束日期.实现的过程走的是程序员开发的老路子,找到轮子后自己改吧改吧就成了.去年做的找不到参考的文章连接了,请原博主见谅. 当时做的时候有几个需求:1. ...

  4. android 自定义view 水波纹进度球

    如果你是老司机,一看标题就会就return吧,嘻嘻. 在我们的日常开发中自定义控件还是用的挺多的,设计师或者产品为了更好的漂亮,美观,交互都会做一些牛逼的ui效果图,但是最后实现的还是我们程序员啊. ...

  5. Android 自定义底部上拉控件的实现

    前言 又到了新的一月,今天提供一个Android自定义底部上拉布局的实现,起因是自己在项目中需要实现这样一个控件,干脆自己写一个练练手. 写完了觉得能想到的需求都基本有了(可能会有其它需求,不过基本上 ...

  6. Android自定义滑动接听电话控件组

    一.目录结构 二.运行效果 三.代码实现 首先,自定义一个类IncomingPhone继承RelativeLayout public IncomingPhone(Context context, At ...

  7. Android自定义多TAB悬浮控件实现蘑菇街首页效果

    原文:http://www.cnblogs.com/ImyFen/archive/2015/11/15/4967127.html 说明: 1.viewpager不能左右滑动: 2.转载时代码略有改动( ...

  8. android自定义view圆,Android自定义View圆形百分比控件(一)

    做一个自定义View的小练习,效果如下 只需要画一个圆.一个圆弧.一个百分比文本,添加一个点击事件,传入百分比重绘 1.在res/values文件夹下新建attrs.xml文件,编写自定义属性: 2. ...

  9. android 星级评论,Android自定义RatingBar(星级评分控件)

    1.首先在Drawable下建立five_rating_bar.xml android:id="@android:id/background" android:drawable=& ...

最新文章

  1. 进程状态控制-进程创建
  2. 每日英语-7/21/2009
  3. python数据类型转换原因_浅谈Python数据类型之间的转换
  4. js cookies 存数组_用一个例子理解JS函数的底层处理机制
  5. 不懂数据库索引原理?因为你心里没有一点B树
  6. 数字后端基础技能之:CTS(中篇)
  7. python表示语句块采用_Python学习日记
  8. linux kernel map
  9. adobe flash player ActiveX IE降级安装旧版本的方法
  10. 易软门诊管理软件php,易软门诊管理系统最新下载
  11. 计算机并口回路测试工具,COM口和LPT口回路环的制作与CheckIT3.0测试方法
  12. ckplayer超酷网页播放器
  13. USB充电限流芯片,5V输入,输出5V,6V触发关闭
  14. QT项目 MyQQ 学习笔记(一)
  15. vue实现输入六位密码支付页面
  16. 直方图代码matlab,MATLAB直方图均衡化代码(MATLAB histogram equalization code).doc
  17. 看过这篇文章,再也不要说你是凭实力单身了
  18. Mac操作系统-软件安装
  19. 本地repos Mac
  20. 【计算机视觉】简述对RandLA-Net(大场景点云)的理解

热门文章

  1. ORACLE SQL开发where子句之case-when
  2. codewars-013: Ease the StockBroker
  3. git 使用及常用命令
  4. Linux基础(9)文本处理三剑客之grep
  5. Android Toast自己定义Toast例子
  6. Windows 2008 R2 SP1部署Lync2010标准版(1)
  7. 利用Caffe训练模型(solver、deploy、train_val) + python如何使用已训练模型
  8. win下配置cmder
  9. mybaits错误解决:There is no getter for property named 'parentId ' in class 'java.lang.String'
  10. 20170523xlVBA多条件分类求和一例