先看效果图:
你可以定义成你项目的logo图片,可以设置水波颜色、波长、波宽、字体大小、颜色、进度条的最大值,当前进度值,还可以设置波纹震动的快慢。当设置一个进度不变的时候,打开时还有一个动画填满的效果(比如第二个流量显示,这里图片没有截出这个效果)。
1. 如何使用
1.1 在布局文件中
添加自定义控件:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><cn<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.fanrunqi</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.waveprogressview</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.WaveProgressView</span> android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@+id/waveProgressbar"</span> android:background=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@drawable/circle"</span> <!--android:background=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@drawable/bg_a"</span>--> android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"130dp"</span> android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"130dp"</span> /></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
说明,这里的android:background定义的是控件的形状,比如上面的圆形和美女,你可用shape.xml定义形状图片。
比如,这是一个圆
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="utf-8"?></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape </span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:shape</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"oval"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">solid</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:color</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"#DDDDDD"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">size</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"150dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"150dp"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
也可以直接给android:background设置一张图片,比如:
这里注意透明像素,还有为了图片缩放的时候不变形,建议背景(不管是图片还是图形)为正方形。
1.2 在代码中
你可以选择进行如下设置:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置当前进度值和当前显示的文字</span> waveProgressbar.setCurrent(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> currentProgress,String currentText); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 77, "788M/1024M"</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置进度条的最大值</span> waveProgressbar.setMaxProgress(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> maxProgress); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置显示文字的大小和颜色</span> waveProgressbar.setText(String mTextColor,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mTextSize);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//"#FFFF00", 41</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置水波的颜色</span> waveProgressbar.setWaveColor(String mWaveColor); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//"#5b9ef4"</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置波浪的高度和波浪的宽度(均为一个波峰的大小)</span> waveProgressbar.setWave(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> mWaveHight,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> mWaveWidth); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置波浪的上下震动的速度(这里注意值越大,震动的越小)</span> waveProgressbar.setmWaveSpeed(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mWaveSpeed);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//The larger the value, the slower the vibration</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>
2. 代码实现
这里实现主要用到的知识有 自定义view、PorterDuffXfermode和二阶贝塞尔曲线,不太清楚的可以在我博客找找,都有的。
首先自定义WaveProgressView继承View,在构造函数中获取布局文件中设置的背景,同时设置一个画波浪的画笔和画文字的画笔。
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">Init</span>() { <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 获得背景 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>==getBackground()){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalArgumentException(String.format(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"background is null."</span>)); }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{ backgroundBitmap = getBitmapFromDrawable(getBackground()); } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 波浪画笔 */</span> mPath = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Path(); mPathPaint = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Paint(); mPathPaint.setAntiAlias(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); mPathPaint.setStyle(Paint.Style.FILL); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 进度画笔 */</span> mTextPaint = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Paint(); mTextPaint.setAntiAlias(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); mTextPaint.setTextAlign(Paint.Align.CENTER); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//开始不断自我绘制,让波浪动起来</span> handler.sendEmptyMessageDelayed(INVALIDATE,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
复写onDraw方法,先把波浪画在画布上,然后画背景(给背景画笔设置PorterDuff.Mode.DST_ATOP模式:取上层非交集部分与下层交集部分 )。当然也可以是PorterDuff.Mode.SRC_ATOP,主要取决于你画的先后顺序。最后把文字画上去,形成一个最终Bitmap,最后把这个Bitmap画到onDraw的参数canvas上。
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> Paint paint = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Paint(); paint.setAntiAlias(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); Bitmap finalBmp = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 产生一个同样大小的画布 */</span> Canvas canvas = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Canvas(finalBmp); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 绘制波浪 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> CurMidY = height*(maxProgress-currentProgress)/maxProgress; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(CurY>CurMidY){ CurY = CurY - (CurY-CurMidY)/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>; } mPath.reset(); mPath.moveTo(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>-distance,CurY); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> waveNum = width/((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)mWaveHalfWidth*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>)+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> multiplier = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i =<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<waveNum*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;i++){ mPath.quadTo(mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)-distance,CurY-mWaveHight,mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>)-distance,CurY); mPath.quadTo(mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>)-distance,CurY+mWaveHight,mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>)-distance,CurY); multiplier+=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>; } distance +=mWaveHalfWidth/mWaveSpeed; distance = distance%(mWaveHalfWidth*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>); mPath.lineTo(width,height); mPath.lineTo(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,height); mPath.close(); canvas.drawPath(mPath, mPathPaint); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 对图片给进行缩放 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> min = Math.min(width,height); backgroundBitmap = Bitmap.createScaledBitmap(backgroundBitmap,min,min,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 使用DST_ATOP,取上层非交集部分与下层交集部分 。 */</span> paint.setXfermode(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> PorterDuffXfermode(PorterDuff.Mode.DST_ATOP)); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 绘制图片 */</span> canvas.drawBitmap(backgroundBitmap,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,paint); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 绘制进度文字 */</span> canvas.drawText(currentText, width/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, height/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, mTextPaint); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> finalBmp;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li></ul>
这里的CurY是上次波浪中线的y轴坐标,CurMidY 是当前的Y轴坐标,每次波浪上升的时候为了不产生卡顿效果,把这1/100的上升分为10次来绘制。
distance是x轴的偏移量,为了使水波动起来,每次绘制时都要向左进行一段偏移。
<code class="hljs glsl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span> +=mWaveHalfWidth/mWaveSpeed; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span> = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span>%(mWaveHalfWidth*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
每次偏移距离为 半波宽度/波浪震动速度,因为一个波是4个半波宽度形成一个循环,然后又回到最开始x位置开始循环位移。
根据view的宽度计算出一共要绘制多少个波形出来,同时多加一个波为了向左平移。
<code class="hljs glsl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> waveNum = width/((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)mWaveHalfWidth*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>)+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> multiplier = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i =<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<waveNum*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>;i++){ mPath.quadTo(mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)-<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span>,CurY-mWaveHight,mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>)-<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span>,CurY); mPath.quadTo(mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>)-<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span>,CurY+mWaveHight,mWaveHalfWidth*(multiplier+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>)-<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">distance</span>,CurY); multiplier+=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
每次绘制以波形的左边点、波形的右边点、view的左下角、view的右下角、形成一个图片把它绘制到内存中新建的和view同大小的canvas上。
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reset</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.moveTo</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>-distance,CurY)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(width,height)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.lineTo</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,height)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> mPath<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.close</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawPath</span>(mPath, mPathPaint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
先对背景图形进行缩放再绘制到canvas上,这里的缩放是按最小边进行缩放。
<code class="hljs glsl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">min</span> = Math.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">min</span>(width,height); backgroundBitmap = Bitmap.createScaledBitmap(backgroundBitmap,<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">min</span>,<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">min</span>,<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
最后把文字绘制上去,注意我们在初始化中设置了画笔,为了能通过代码设置文字的颜色,要把设置文字画笔颜色和大小放在onDraw方法中。
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> mPathPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setColor</span>(Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parseColor</span>(mWaveColor))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> mTextPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setColor</span>(Color<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parseColor</span>(mTextColor))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> mTextPaint<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setTextSize</span>(mTextSize)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> canvas<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.drawText</span>(currentText, width/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, height/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, mTextPaint)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
为了使波浪动起来,使用handler循环调用invalidate刷新界面。同时应该在构造函数打开handler循环。
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> INVALIDATE = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0X777</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Handler handler = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Handler() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">handleMessage</span>(Message msg) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.handleMessage(msg); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (msg.what) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> INVALIDATE: invalidate(); sendEmptyMessageDelayed(INVALIDATE,RefreshGap); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; } } };</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
最后就是一些相关属性设置的函数。
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> currentProgress 当前进度 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> currentText 当前显示的进度文字 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setCurrent</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> currentProgress,String currentText) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.currentProgress = currentProgress; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.currentText = currentText; } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> maxProgress 设置进度条的最大值,默认100 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setMaxProgress</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> maxProgress){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.maxProgress = maxProgress; } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> mTextColor 文字的颜色 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> mTextSize 文字的大小 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setText</span>(String mTextColor,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mTextSize){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mTextColor = mTextColor; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mTextSize = mTextSize; } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> mWaveHight 波峰的高度 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> mWaveWidth 一个波峰的宽度 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setWave</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> mWaveHight,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> mWaveWidth){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mWaveHight = mWaveHight; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mWaveHalfWidth = mWaveWidth/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>; } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> mWaveColor 水的颜色 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setWaveColor</span>(String mWaveColor){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mWaveColor = mWaveColor; } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 值越大震荡的越慢 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> mWaveSpeed */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setmWaveSpeed</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> mWaveSpeed){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mWaveSpeed = mWaveSpeed; </code><p><code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> }</code><code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> </code><code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> </code><code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">from:http://blog.csdn.net/amazing7/article/details/51855165</code></p>