自定义控件三部曲之绘图篇(十九)——LinearGradient与闪动文字效果
2016-09-08 16:35
531 查看
前言:家和万事兴
相关文章:
《Android自定义控件三部曲文章索引》:http://blog.csdn.net/harvic880925/article/details/50995268
博主这段时间工作实在是太忙了,全天无尿点……博客一直没更新,实在对不住大家……
这篇就给大家讲setShader的另一个参数,LinearGradient,使用过shape标签的同学,对这个方法估计都不莫生,就是线性渐变。跟PhotoShop中的线性渐变的原理和作用是一样的。这篇文章的最终会实现一个闪动文字效果控件:
有关渐变,以前有讲过一篇《详解shape标签》,其中讲述了
其中的渐变类型有”linear” | “radial” | “sweep”,在代码中对应的类分别是LinearGradient、RaialGradient、SweepGradient;有关
这篇我们要讲就是线性渐变的LinearGradient;
我们先来看下LinearGradient的构造函数:
第一个构造函数:
用过PhotoShop的线性激变工具的同学,应该都知道,线性渐变其实是在指定的两个点之间填充渐变颜色。
- 参数中的(x0,y0)就是起始渐变点坐标,参数中(x1,y1)就是结束渐变点坐标;
- color0就是起始颜色,color1就是终止颜色;颜色值必须使用0xAARRGGBB形式的16进制表示!表示透明度的AA一定不能少。
- TileMode tile:与BitmapShader一样,用于指定控件区域大于指定的渐变区域时,空白区域的颜色填充方法。
很显然!这个方法,只能指定两种颜色之间的渐变。如果需要多种颜色之间的渐变,就需要使用下面的这个构造函数了。
第二个构造函数:
同样,(x0,y0)就是起始渐变点坐标,参数中(x1,y1)就是结束渐变点坐标
colors[]用于指定渐变的颜色值数组,同样,颜色值必须使用0xAARRGGBB形式的16进制表示!表示透明度的AA一定不能少。
positions[]与渐变的颜色相对应,取值是0-1的float类型,表示在每一个颜色在整条渐变线中的百分比位置
我们先来看看两色渐变的构造函数是如何来使用的:
很简单,只需要在绘图的时候构造LinearGradient实例,通过Paint.setShader设置进去即可。
大家注意一下,我这里设置的渐变范围是从控件的左边中点到右边中点:
最后通过canvas.drawRect把整个控件区域画出来:
这里大家注意一下,上面我们也已经提到了,颜色值必须使用0xAARRGGBB的完整16进制的颜色样式表示,我们这里的颜色值就是0xffff0000和0xff00ff00;大家自己可以进行尝试,如果把红色的透明度值去掉,改写成0xff00000,是不会有任何显示的。
效果图如下:
下面我们来看第二个构造函数,多色渐变的使用方法:
从这里可以看出,渐变的开始点同样是控件左边中点,渐变的结束点也同样是控件右边中点;这里我们指定了五种渐变颜色,而且指定了每个颜色的位置,前四种颜色是按20%均匀分布的,最后两种颜色相距40%;最后通过canvas.drawRect把整个控件区域画出来
效果图如下:
注意:
colors和pos的个数一定要相等,也就是说必须指定每一个颜色值的位置!如果多或少都会直接报错:(Signal 11是SO内部错误)
我们上面的示例中都是从控件左边中间到控件右边中点;如果我们改成从左上角到右上角的填充方式,结果会怎样呢?
渐变线是从控件的左上角到控件的右下角位置:
效果图如下:
形成原理如下:
就是说,首先是两个渐变点之间连线,然后以连线为对角线形成一个矩形,各种颜色都是以这条对角线为矩形的填充的。
在讲到BitmapShader的时候,我们已经详细讲过TileMode的意义:当控件区域大小渐变区域时,用于填充空白位置的。
下面我们就逐个看一下TileMode不同时,对于线性渐变的有什么作用。
(1)、X、Y轴共用填充参数
首先,我们再回来看一下LinearGradient的构造函数:
从构造函数中可以看出,LiearGradient只有一个TileMode参数,这说明X轴与Y轴共用这一个TileMode填充参数,而不能像BitmapShader那样分别指定X轴与Y轴的填充参数。
(2)、TileMode.CLAMP
这里做了一个多色渐变,渐变点是从(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
同样,如果我们把填充模式改为镜像模式,效果图如下:
很容易理解,就不再讲了。
与BitmapShader一样,同样是从控件左上角开始填充整个控件,利用canvas.drawXXX系列函数只是用来指定显示哪一块
比如:
同样是使用镜像模式,但我们不再全屏绘制,而只是绘出其中一小部分:
我们再来看看全屏绘制的镜像模式的效果图:
很明显,这里所绘制的一小块,跟从全屏绘制的效果图上摘下来的一块一样。
这就说明了:
无论哪种Shader,都是从控件的左上角开始填充的,利用canvas.drawXXX系列函数只是用来指定显示哪一块
我们说了如果利用drawXXX系列函数只是用来指定显示哪一块,那如果我们利用DrawText来显示,那是不是就会显示出彩色文字了?
效果图如下:
有没有感觉很酷炫……看似牛逼的效果其实就是这么简单……
如果我们把渐变效果移动起来,就直接实现了我们开篇时说的文字渐变的动画效果了。
下面我们加入动画,让颜色动起来吧
这部分我们要实现的效果图如下:
闪光效果有木有……看起来很碉堡吧,我们就来具体看下原理吧,这个控件只给大家讲基本原理,就不再封装成控件了,博主近期太忙了,大家自己封装下吧……
我们先来看下原理图:
首先,我们要有一个渐变的LinearGradient,颜色是从文字颜色的黑色到中间的绿色,然后再到黑色,填充模式为 Shader.TileMode.CLAMP,初始的位置在文字的左侧;
对应图像为:
我这里为了表述文字效果,特地做了几个处理;
1.首先我把渐变图像用红边框了起来。由于填充模式是Shader.TileMode.CLAMP,所以右侧文字的位置会被填充为边缘颜色黑色
2.为了表述当前文字的位置,我特地把文字写成了红色。而文字真正的颜色应该是其底部LinearGradient的填充色才对的,大家这点注意。
对应代码为:
下图显示的是当渐变的LinearGradient移动到文字部分的时的状态
由于使用的是Shader.TileMode.CLAMP填充模式,所以两次空白区域都会被填充为LinearGradient的边缘颜色,即文字的黑色。
上面我们讲了,文字会显示其下方LinearGradient的填充颜色,所以现在文字的文字就会有一部分变绿了。
在终止状态时,LinearGradient移动到文字的右侧
同样是由于Shader.TileMode.CLAMP填充模式,文字会被填充为文字原本的颜色。
从上面的原理中,我们需要理出来几个点:
第一:创建的LinearGradient渐变的构造方法,前面已经列出来代码了,初始位置是在文字左侧的,而且大小与文字所占位置相同,填充模式使用边缘填充
第二:从起始位置和终止位置可以看出,LinearGradient渐变的运动长度是两个文字的长度。
其实看了原理之后,实现起来就没有什么难度了,我们还是列出完整代码,然后针对性的讲一点就可以了,如果大家还没看懂,可以把示例源码下下来,自己再研究研究
1、派生自TextView
首先需要注意的是,控件派生自TextView,所以可以使用TextView的自带方法getCurrentTextColor()来获取文字颜色。
2、如何移动LinearGradient
然后,上面我们讲了如何给文字加上渐变效果,其实让它动起来办法很简单,还记得我们说过Shader有一个setLocalMatrix(Matrix localM) 方法可以设置位置矩阵么,我们只需要给LinearGradient设置上逐渐平移的矩阵就可以了。
比如:
其中向右偏移的距离mDx,是由ValueAnimator生成的;
3、ValueAnimator的创建
前面我们讲了LinearGradient移动距离是从0到两倍的text距离,我们通过getMeasuredWidth()可以得到TextView的宽度,乘以2就可以了,创建代码如下:
有关ValueAnimator的使用方法,如果有不理解的同学,请先去看《Android自定义三部曲之动画篇》;
好了,本篇到这里就结束了,下篇我们再来看最后一个渐变RadialGradient的使用方法与效果吧。
如果本文有帮到你,记得加关注哦
源码下载地址:http://download.csdn.net/detail/harvic880925/9615494
转载请标明出处,http://blog.csdn.net/harvic880925/article/details/52350154谢谢
相关文章:
《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谢谢
相关文章推荐
- 自定义控件三部曲之绘图篇(十九)——LinearGradient与闪动文字效果
- Android开发 之 LinearGradient与闪动文字效果
- 自定义控件三部曲之绘图篇(二十)——RadialGradient与水波纹按钮效果
- 自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果
- 自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果
- 自定义控件三部曲之绘图篇(十八)——BitmapShader与望远镜效果
- 自定义控件三部曲之绘图篇(六)——Path之贝赛尔曲线和手势轨迹、水波纹效果
- 自定义控件三部曲之绘图篇(八)——Paint之ColorMatrix与滤镜效果
- 自定义控件三部曲之绘图篇(八)——Paint之ColorMatrix与滤镜效果
- android 使用LinearGradient实现手机开机文字闪烁效果
- 自定义控件三部曲之绘图篇(十六)——给控件添加阴影效果与发光效果
- linear-gradient实现纯CSS文字淡入效果
- LinearGradient线性渲染实现绚丽的闪动字效果
- 自定义控件三部曲之绘图篇(十六)——给控件添加阴影效果与发光效果
- 自定义控件三部曲之绘图篇(十五)——QQ红点拖动删除效果实现(基本原理篇)
- 自定义控件三部曲之绘图篇(十五)——QQ红点拖动删除效果实现(基本原理篇)
- 自定义控件三部曲之绘图篇(十五)——QQ红点拖动删除效果实现(基本原理篇)
- 自定义控件三部曲之绘图篇(十五)——QQ红点拖动删除效果实现(基本原理篇)
- 利用LinearGradient Shader和Matrix来实现动态文字闪动效果
- 自定义控件三部曲之绘图篇(十六)——给控件添加阴影效果与发光效果