自定义WaveProgressView

先看效果图:

这里写图片描述

  你可以定义成你项目的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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值