Android Shader子类LinearGradient

用来实现线性渐变效果

此类是Shader的子类
通过paint.setShader来设置渐变。

有两个构造方法分别如下:

  1. LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[], TileMode tile)
    注:Android中计算x,y坐标都是以屏幕左上角为原点,向右为x+,向下为y+
    第一个参数为线性起点的x坐标
    第二个参数为线性起点的y坐标
    第三个参数为线性终点的x坐标
    第四个参数为线性终点的y坐标
    第五个参数为实现渐变效果的颜色的组合
    第六个参数为前面的颜色组合中的各颜色在渐变中占据的位置(比重),如果为空,则表示上述颜色的集合在渐变中均匀出现
    第七个参数为渲染器平铺的模式,一共有三种

    -CLAMP
    边缘拉伸
    -REPEAT
    在水平和垂直两个方向上重复,相邻图像没有间隙
    -MIRROR
    以镜像的方式在水平和垂直两个方向上重复,相邻图像有间隙

  2. public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, TileMode tile)
    其他参数同上
    int color0表示渐变起始颜色
    int color1表示渐变终止颜色

下面主要来演示一下第一种构造方法下的实现效果:
首先是

LinearGradient mLinearGradient = new LinearGradient(0,0,getMeasuredWidth(),0,new int[]{Color.WHITE,Color.BLACK,Color.YELLOW},new float[]{0,0.5f,1.0f}, Shader.TileMode.CLAMP);

 

即实现白黑黄三色渐变。


Paste_Image.png


然后通过改变float数组中的中间值为0.8f:


Paste_Image.png


然后将中间值在设为0.5f,方便后面测试。
将x坐标改为从0到0
将y坐标改为从0到getMeasuredHeight();


Paste_Image.png


效果很显然,变成纵向的渐变了
然后将将x坐标改为从0到getMeasuredWidth();
将y坐标改为从0到getMeasuredHeight();


Paste_Image.png

果然,变成斜线渐变了。
如果我将x改为从getMeasuredWidth到0呢?


Paste_Image.png

果然不出所料,渐变反过来了。
接下来测试下渲染平铺模式
前面一直用的是CLAMP
尝试将x改为0到getMeasuredWidth()/2;


Paste_Image.png


只有左边的一部分进行了渲染,右边半部分则是使用渲染最后的颜色进行了填充。
将模式改为REPEAT


Paste_Image.png


再将模式改为MIRROR


Paste_Image.png


可以明显看到两者的区别
或者,
我们再将y设为0到getMeasuredHeight()/4
x设为0到getMeasuredWidth()/4

REPEAT


Paste_Image.png

MIRROR


Paste_Image.png


这样一来就显示的更清楚了

REPEAT指的是单纯的重复
白黑黄-白黑黄-白黑黄-白黑黄

MIRROR则是镜像
白黑黄-黄黑白-白黑黄-黄黑白

至于前面说的两者重复中间是否有间隔
从图上好像确实看不出来
我感觉应该是因为镜像的话中间部分的颜色是一样的,因此看起来中间并没有间隔,而重复的话一般而言重复连接部分的颜色是有差别的,这样就会导致看起来在衔接部分是有间隔的。

第二个构造方法简单也试一下:


Paste_Image.png


比较简单,就是两色渐变。

使用LinearGradient配合Matrix实现文字闪动效果:

首先需要设置渐变(在onSizeChaged方法中实现)
mLinearGradient = new LinearGradient(0,0,mViewWidth,0,new int[]{Color.BLUE,0xffffffff,Color.BLUE},null, Shader.TileMode.CLAMP);
然后,在onDra()方法中,调用如下代码:
if(mGradientMatrix != null){ //从0开始,每次递增mViewWidth / 5,即从最左侧开始每次向前平移1/5个长度 mTransLate += (mViewWidth / 5); if(mTransLate > mViewWidth){ //渐变平移走到头,需要重新从头开始 mTransLate = -mViewWidth; } mGradientMatrix.setTranslate(mTransLate,0); mLinearGradient.setLocalMatrix(mGradientMatrix); postInvalidateDelayed(1000); }
Matrix表示变换矩阵
其中的setTranslate表示平移,两个参数分别为x和y方向平移量
setLocalMatrix方法是Shader类的方法
表示 设置shader的本地矩阵

上述代码意思就是,设置一个偏移量,每次递增1/5View的长度,进行平移,当该长度递增超过了View的长度时就将其平移回最左侧,再从头开始。
其中的setLocalMatrix设置了渐变的平移矩阵
postInvalidateDelayed表示延迟重绘

如图所示:


Paste_Image.png


蓝色为起点,绿色为最右侧,橙色为最左侧,白框为手机。

解释:
上面设置了渐变的长度是0到getMeasuredWidth(),那么按照我们上面的测试来看的话,应该是一个长度为getMeasuredWidth()这样的静态的渐变方案,渐变部分主要在中间,两侧的颜色依旧是设置的颜色,然后,对这个的容器整体上进行平移,即将这个渐变看做一个长方形,对这个长方形进行平移,那么就可以实现对整个渐变进行平移,上述代码在最开始运行的时候,渐变应该是从屏幕正中间开始的,然后一直将该长方形整个平移至屏幕右侧外,然后再将其平移至屏幕左侧外,再向右进行。就能实现视觉效果上的文字闪动效果。
主要就是对渐变进行了平移。

注:所有的平移的参考点都是初始点。


链接:http://www.jianshu.com/p/a9d09cb7577f
posted @ 2017-08-22 14:23  猴子1  阅读(703)  评论(0编辑  收藏  举报