自定義控件三部曲之繪圖篇(十九)——LinearGradient與閃動文字效果

前言:家和萬事興

相關文章: 
Android自定義控件三部曲文章索引》http://blog.csdn.net/harvic880925/article/details/50995268

博主這段時間工作實在是太忙了,全天無尿點……博客一直沒更新,實在對不住大家……

這篇就給大家講setShader的另一個參數,LinearGradient,使用過shape標籤的同學,對這個方法估計都不莫生,就是線性漸變。跟PhotoShop中的線性漸變的原理和作用是一樣的。這篇文章的最終會實現一個閃動文字效果控件:
這裏寫圖片描述

一、引言

有關漸變,以前有講過一篇《詳解shape標籤》,其中講述了<gradient/>標籤的用法:

<code class="language-xml hljs  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-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);">gradient</span>   
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">["linear"</span> | "<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">radial</span>" | "<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">sweep</span>"]    //共有<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">3</span>中漸變類型,線性漸變(默認)/放射漸變/掃描式漸變    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:angle</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"integer"</span>     //漸變角度,必須爲<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">45</span>的倍數,<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">0</span>爲從左到右,<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">90</span>爲從上到下    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:centerX</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"float"</span>     //漸變中心<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">X</span>的相當位置,範圍爲<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">0</span>~<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">1</span>    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:centerY</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"float"</span>     //漸變中心<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">Y</span>的相當位置,範圍爲<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">0</span>~<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">1</span>    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:startColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"color"</span>   //漸變開始點的顏色    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:centerColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"color"</span>  //漸變中間點的顏色,在開始與結束點之間    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:endColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"color"</span>    //漸變結束點的顏色    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:gradientRadius</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"float"</span>  //漸變的半徑,只有當漸變類型爲<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">radial</span>時才能使用    
    <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:useLevel</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">["true"</span> | "<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">false</span>"] /></span>  //使用LevelListDrawable時就要設置爲true。設爲false時纔有漸變效果    </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></ul><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></ul>

其中的漸變類型有”linear” | “radial” | “sweep”,在代碼中對應的類分別是LinearGradient、RaialGradient、SweepGradient;有關<gradient/>各個漸變效果的用法,不知道的同學強烈建議你先看看這篇文章。 
這篇我們要講就是線性漸變的LinearGradient;

二、LinearGradient基本使用

1、構造函數

我們先來看下LinearGradient的構造函數: 
第一個構造函數:

<code class="language-java hljs  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;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradient</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x1, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y1,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> color0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> color1, TileMode tile)</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></ul><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></ul>

用過PhotoShop的線性激變工具的同學,應該都知道,線性漸變其實是在指定的兩個點之間填充漸變顏色。 
- 參數中的(x0,y0)就是起始漸變點座標,參數中(x1,y1)就是結束漸變點座標; 
- color0就是起始顏色,color1就是終止顏色;顏色值必須使用0xAARRGGBB形式的16進製表示!表示透明度的AA一定不能少。 
- TileMode tile:與BitmapShader一樣,用於指定控件區域大於指定的漸變區域時,空白區域的顏色填充方法。

很顯然!這個方法,只能指定兩種顏色之間的漸變。如果需要多種顏色之間的漸變,就需要使用下面的這個構造函數了。

第二個構造函數:

<code class="language-java hljs  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;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradient</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x1, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y1,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> colors[], <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> positions[], TileMode tile)</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></ul><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></ul>

同樣,(x0,y0)就是起始漸變點座標,參數中(x1,y1)就是結束漸變點座標 
colors[]用於指定漸變的顏色值數組,同樣,顏色值必須使用0xAARRGGBB形式的16進製表示!表示透明度的AA一定不能少。 
positions[]與漸變的顏色相對應,取值是0-1的float類型,表示在每一個顏色在整條漸變線中的百分比位置

2、兩色漸變使用示例

我們先來看看兩色漸變的構造函數是如何來使用的:

<code class="language-java hljs  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;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">LinearGradientView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">View</span> {</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Paint mPaint;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradientView</span>(Context context) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context);
        init();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradientView</span>(Context context, AttributeSet attrs) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs);
        init();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradientView</span>(Context context, AttributeSet attrs, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> defStyle) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs, defStyle);
        init();
    }

    <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>(){
        setLayerType(LAYER_TYPE_SOFTWARE,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);
        mPaint = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Paint();
    }

    <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;">protected</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;">onDraw</span>(Canvas canvas) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
        mPaint.setShader(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,getWidth(),getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>, Shader.TileMode.CLAMP));
        canvas.drawRect(<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>,getWidth(),getHeight(),mPaint);
    }
}</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></ul><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></ul>

很簡單,只需要在繪圖的時候構造LinearGradient實例,通過Paint.setShader設置進去即可。 
大家注意一下,我這裏設置的漸變範圍是從控件的左邊中點到右邊中點:

<code class="language-java hljs  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;">mPaint.setShader(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,getWidth(),getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>, Shader.TileMode.CLAMP));</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></ul><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></ul>

最後通過canvas.drawRect把整個控件區域畫出來:

<code class="language-java hljs  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;">canvas.drawRect(<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>,getWidth(),getHeight(),mPaint);</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></ul><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></ul>

這裏大家注意一下,上面我們也已經提到了,顏色值必須使用0xAARRGGBB的完整16進制的顏色樣式表示,我們這裏的顏色值就是0xffff0000和0xff00ff00;大家自己可以進行嘗試,如果把紅色的透明度值去掉,改寫成0xff00000,是不會有任何顯示的。 
效果圖如下: 
這裏寫圖片描述

3、多色漸變使用示例

下面我們來看第二個構造函數,多色漸變的使用方法:

<code class="language-java hljs  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;">protected</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;">onDraw</span>(Canvas canvas) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[] colors = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000ff</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffffff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ffff</span>};
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]  pos = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.2</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.4</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.6</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>f};
    LinearGradient multiGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,getWidth(),getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,colors,pos, Shader.TileMode.CLAMP);
    mPaint.setShader(multiGradient);
    canvas.drawRect(<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>,getWidth(),getHeight(),mPaint);
}</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><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>

從這裏可以看出,漸變的開始點同樣是控件左邊中點,漸變的結束點也同樣是控件右邊中點;這裏我們指定了五種漸變顏色,而且指定了每個顏色的位置,前四種顏色是按20%均勻分佈的,最後兩種顏色相距40%;最後通過canvas.drawRect把整個控件區域畫出來

效果圖如下: 
這裏寫圖片描述

注意: 
colors和pos的個數一定要相等,也就是說必須指定每一個顏色值的位置!如果多或少都會直接報錯:(Signal 11是SO內部錯誤) 
這裏寫圖片描述

2、漸變起始座標與填充的關係——矩形填充

我們上面的示例中都是從控件左邊中間到控件右邊中點;如果我們改成從左上角到右上角的填充方式,結果會怎樣呢?

<code class="language-java hljs  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;">protected</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;">onDraw</span>(Canvas canvas) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[] colors = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000ff</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffffff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ffff</span>};
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]  pos = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.2</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.4</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.6</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>f};
    LinearGradient multiGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<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>,getWidth(),getHeight(),colors,pos, Shader.TileMode.CLAMP);
    mPaint.setShader(multiGradient);
    canvas.drawRect(<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>,getWidth(),getHeight(),mPaint);
}        </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><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>

漸變線是從控件的左上角到控件的右下角位置:

<code class="language-java hljs  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;">LinearGradient multiGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<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>,getWidth(),getHeight(),colors,pos, Shader.TileMode.CLAMP);</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></ul><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></ul>

效果圖如下: 
這裏寫圖片描述 
形成原理如下: 
這裏寫圖片描述 
就是說,首先是兩個漸變點之間連線,然後以連線爲對角線形成一個矩形,各種顏色都是以這條對角線爲矩形的填充的。

3、TileMode重複方式

在講到BitmapShader的時候,我們已經詳細講過TileMode的意義:當控件區域大小漸變區域時,用於填充空白位置的。 
下面我們就逐個看一下TileMode不同時,對於線性漸變的有什麼作用。 
(1)、X、Y軸共用填充參數 
首先,我們再回來看一下LinearGradient的構造函數:

<code class="language-java hljs  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;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradient</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x1, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y1,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> colors[], <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> positions[], TileMode tile)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">LinearGradient</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x1, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y1,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> color0, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> color1, TileMode tile)</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><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>

從構造函數中可以看出,LiearGradient只有一個TileMode參數,這說明X軸與Y軸共用這一個TileMode填充參數,而不能像BitmapShader那樣分別指定X軸與Y軸的填充參數。 
(2)、TileMode.CLAMP

<code class="language-java hljs  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;">protected</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;">onDraw</span>(Canvas canvas) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
<span class="hljs-comment" 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>[] colors = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000ff</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffffff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ffff</span>};
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]  pos = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.2</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.4</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.6</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>f};
    LinearGradient multiGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<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>,getWidth()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,colors,pos, Shader.TileMode.CLAMP);
    mPaint.setShader(multiGradient);
    canvas.drawRect(<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>,getWidth(),getHeight(),mPaint);
}</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></ul><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></ul>

這裏做了一個多色漸變,漸變點是從(0,0)到屏幕的中間點(width/2,height.2); 
效果圖如下: 
這裏寫圖片描述 
從效果圖中可以看到,效果很好理解,就是以(0,0)到(width/2,height.2)爲矩形對角線,來填充各種顏色漸變,對於之外的區域,用邊緣色彩來填充。 
(3)、TileMode.REPEAT 
同樣是上面的代碼,漸變點是從(0,0)到屏幕的中間點(width/2,height.2),當空白區域填充模式改爲TileMode.REPEAT時,效果圖如下: 
這裏寫圖片描述 
大家初次看到這個效果,可能一臉懵逼 —_—!!!, 其實也不難理解,我們需要先找到哪塊是我們的漸變,哪塊是空白像素的填充: 
這裏寫圖片描述

在這個圖中,藍色塊是我們原始的漸變圖形,從從(0,0)到屏幕的中間點(width/2,height.2),另外的沒有遮起來的部分是空白位置填充的。 
在填充時,結束點做爲填充點的起點,即填充的線性漸變的位置爲從(width/2,height/2)到(width,height),即從中間點到右下角點位置的填充。 
(4)、TileMode.MIRROR 
同樣,如果我們把填充模式改爲鏡像模式,效果圖如下: 
這裏寫圖片描述 
很容易理解,就不再講了。

4、填充方式:從控件左上角開始填充

與BitmapShader一樣,同樣是從控件左上角開始填充整個控件,利用canvas.drawXXX系列函數只是用來指定顯示哪一塊 
比如:

<code class="language-java hljs  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;">protected</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;">onDraw</span>(Canvas canvas) {
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
     <span class="hljs-comment" 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>[] colors = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000ff</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffffff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ffff</span>};
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]  pos = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.2</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.4</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.6</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>f};
     LinearGradient multiGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<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>,getWidth()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,colors,pos, Shader.TileMode.MIRROR);
     mPaint.setShader(multiGradient);
     canvas.drawRect(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>,mPaint);
 }</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></ul><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></ul>

同樣是使用鏡像模式,但我們不再全屏繪製,而只是繪出其中一小部分: 
這裏寫圖片描述 
我們再來看看全屏繪製的鏡像模式的效果圖: 
這裏寫圖片描述 
很明顯,這裏所繪製的一小塊,跟從全屏繪製的效果圖上摘下來的一塊一樣。

這就說明了: 
無論哪種Shader,都是從控件的左上角開始填充的,利用canvas.drawXXX系列函數只是用來指定顯示哪一塊

我們說了如果利用drawXXX系列函數只是用來指定顯示哪一塊,那如果我們利用DrawText來顯示,那是不是就會顯示出彩色文字了?

<code class="language-java hljs  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;">protected</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;">onDraw</span>(Canvas canvas) {
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
   <span class="hljs-comment" 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>[] colors = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffff0000</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff0000ff</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffffff00</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ffff</span>};
   <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]  pos = {<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.2</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.4</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.6</span>f,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.0</span>f};
   LinearGradient multiGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(<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>,getWidth()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,getHeight()/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,colors,pos, Shader.TileMode.MIRROR);
   mPaint.setShader(multiGradient);
   mPaint.setTextSize(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">50</span>);
   canvas.drawText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"歡迎關注啓艦的blog"</span>,<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;">200</span>,mPaint);
}</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></ul><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></ul>

效果圖如下: 
這裏寫圖片描述 
有沒有感覺很酷炫……看似牛逼的效果其實就是這麼簡單…… 
如果我們把漸變效果移動起來,就直接實現了我們開篇時說的文字漸變的動畫效果了。 
下面我們加入動畫,讓顏色動起來吧

三、閃光字符串實現

這部分我們要實現的效果圖如下: 
這裏寫圖片描述 
閃光效果有木有……看起來很碉堡吧,我們就來具體看下原理吧,這個控件只給大家講基本原理,就不再封裝成控件了,博主近期太忙了,大家自己封裝下吧…… 
我們先來看下原理圖:

1、原理

(1)、初始狀態

首先,我們要有一個漸變的LinearGradient,顏色是從文字顏色的黑色到中間的綠色,然後再到黑色,填充模式爲 Shader.TileMode.CLAMP,初始的位置在文字的左側; 
對應圖像爲: 
這裏寫圖片描述 
我這裏爲了表述文字效果,特地做了幾個處理; 
1.首先我把漸變圖像用紅邊框了起來。由於填充模式是Shader.TileMode.CLAMP,所以右側文字的位置會被填充爲邊緣顏色黑色 
2.爲了表述當前文字的位置,我特地把文字寫成了紅色。而文字真正的顏色應該是其底部LinearGradient的填充色纔對的,大家這點注意。 
對應代碼爲:

<code class="language-java hljs  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;">mLinearGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(- getMeasuredWidth(),<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>,<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;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[]{
        getCurrentTextColor(),<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,getCurrentTextColor()},
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]{
                <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.5</span>f,
                <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
        },
        Shader.TileMode.CLAMP
    );
}</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></ul><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></ul>

(2)、運動中

下圖顯示的是當漸變的LinearGradient移動到文字部分的時的狀態 
這裏寫圖片描述 
由於使用的是Shader.TileMode.CLAMP填充模式,所以兩次空白區域都會被填充爲LinearGradient的邊緣顏色,即文字的黑色。 
上面我們講了,文字會顯示其下方LinearGradient的填充顏色,所以現在文字的文字就會有一部分變綠了。

(3)、終止狀態

在終止狀態時,LinearGradient移動到文字的右側 
這裏寫圖片描述 
同樣是由於Shader.TileMode.CLAMP填充模式,文字會被填充爲文字原本的顏色。

從上面的原理中,我們需要理出來幾個點: 
第一:創建的LinearGradient漸變的構造方法,前面已經列出來代碼了,初始位置是在文字左側的,而且大小與文字所佔位置相同,填充模式使用邊緣填充 
第二:從起始位置和終止位置可以看出,LinearGradient漸變的運動長度是兩個文字的長度。

二、代碼實現

其實看了原理之後,實現起來就沒有什麼難度了,我們還是列出完整代碼,然後針對性的講一點就可以了,如果大家還沒看懂,可以把示例源碼下下來,自己再研究研究

<code class="language-java hljs  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;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ShimmerTextView</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">TextView</span> {</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Paint mPaint;
    <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;">int</span> mDx;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> LinearGradient mLinearGradient;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ShimmerTextView</span>(Context context) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context);
        init();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ShimmerTextView</span>(Context context, AttributeSet attrs) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs);
        init();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">ShimmerTextView</span>(Context context, AttributeSet attrs, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> defStyle) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>(context, attrs, defStyle);
        init();
    }

    <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>(){
        mPaint =getPaint();
    }

    <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;">protected</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;">onLayout</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> changed, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> left, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> top, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> right, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> bottom) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onLayout(changed, left, top, right, bottom);

        ValueAnimator animator = ValueAnimator.ofInt(<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;">2</span>*getMeasuredWidth());
        animator.addUpdateListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ValueAnimator.AnimatorUpdateListener() {
            <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;">onAnimationUpdate</span>(ValueAnimator animation) {
                mDx = (Integer) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setDuration(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2000</span>);
        animator.start();

        mLinearGradient = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> LinearGradient(- getMeasuredWidth(),<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>,<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;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[]{
                getCurrentTextColor(),<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xff00ff00</span>,getCurrentTextColor()
        },
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span>[]{
                        <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.5</span>f,
                        <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
                },
                Shader.TileMode.CLAMP
        );
    }

    <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;">protected</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;">onDraw</span>(Canvas canvas) {

        Matrix matrix = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Matrix();
        matrix.setTranslate(mDx,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
        mLinearGradient.setLocalMatrix(matrix);
        mPaint.setShader(mLinearGradient);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
    }
}</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><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li></ul><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><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li></ul>

1、派生自TextView 
首先需要注意的是,控件派生自TextView,所以可以使用TextView的自帶方法getCurrentTextColor()來獲取文字顏色。 
2、如何移動LinearGradient 
然後,上面我們講了如何給文字加上漸變效果,其實讓它動起來辦法很簡單,還記得我們說過Shader有一個setLocalMatrix(Matrix localM) 方法可以設置位置矩陣麼,我們只需要給LinearGradient設置上逐漸平移的矩陣就可以了。 
比如:

<code class="language-java hljs  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-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;">protected</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;">onDraw</span>(Canvas canvas) {

    Matrix matrix = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Matrix();
    matrix.setTranslate(mDx,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
    mLinearGradient.setLocalMatrix(matrix);
    mPaint.setShader(mLinearGradient);

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDraw(canvas);
}</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></ul><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></ul>

其中向右偏移的距離mDx,是由ValueAnimator生成的; 
3、ValueAnimator的創建 
前面我們講了LinearGradient移動距離是從0到兩倍的text距離,我們通過getMeasuredWidth()可以得到TextView的寬度,乘以2就可以了,創建代碼如下:

<code class="language-java hljs  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;">ValueAnimator animator = ValueAnimator.ofInt(<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;">2</span>*getMeasuredWidth());
animator.addUpdateListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ValueAnimator.AnimatorUpdateListener() {
    <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;">onAnimationUpdate</span>(ValueAnimator animation) {
        mDx = (Integer) animation.getAnimatedValue();
        postInvalidate();
    }
});
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setDuration(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2000</span>);
animator.start();</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><div class="save_code tracking-ad" data-mod="popu_249" style="box-sizing: border-box; position: absolute; height: 60px; right: 30px; top: 5px; color: rgb(255, 255, 255); cursor: pointer; z-index: 2;"><a target=_blank target="_blank" style="color: rgb(51, 102, 153); box-sizing: border-box;"><img src="http://static.blog.csdn.net/images/save_snippets.png" style="border: none; box-sizing: border-box; max-width: 100%;" alt="" /></a></div><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>

有關ValueAnimator的使用方法,如果有不理解的同學,請先去看《Android自定義三部曲之動畫篇》;

好了,本篇到這裏就結束了,下篇我們再來看最後一個漸變RadialGradient的使用方法與效果吧。

如果本文有幫到你,記得加關注哦 
源碼下載地址:http://download.csdn.net/detail/harvic880925/9615494 
轉載請標明出處,http://blog.csdn.net/harvic880925/article/details/52350154謝謝

發佈了7 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章