Android Shader子类LinearGradient
用来实现线性渐变效果
此类是Shader的子类
通过paint.setShader来设置渐变。
有两个构造方法分别如下:
-
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
以镜像的方式在水平和垂直两个方向上重复,相邻图像有间隙 -
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);
即实现白黑黄三色渐变。
![](http://upload-images.jianshu.io/upload_images/3158352-a2eb034fc800b07c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
然后通过改变float数组中的中间值为0.8f:
![](http://upload-images.jianshu.io/upload_images/3158352-692c6f0ad0b0bfbf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
然后将中间值在设为0.5f,方便后面测试。
将x坐标改为从0到0
将y坐标改为从0到getMeasuredHeight();
![](http://upload-images.jianshu.io/upload_images/3158352-454d4de74da98f87.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
效果很显然,变成纵向的渐变了
然后将将x坐标改为从0到getMeasuredWidth();
将y坐标改为从0到getMeasuredHeight();
![](http://upload-images.jianshu.io/upload_images/3158352-464eb6bfe7f94eeb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
果然,变成斜线渐变了。
如果我将x改为从getMeasuredWidth到0呢?
![](http://upload-images.jianshu.io/upload_images/3158352-18ba15b4f056b342.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
果然不出所料,渐变反过来了。
接下来测试下渲染平铺模式
前面一直用的是CLAMP
尝试将x改为0到getMeasuredWidth()/2;
![](http://upload-images.jianshu.io/upload_images/3158352-35c2a7a9feafffed.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
只有左边的一部分进行了渲染,右边半部分则是使用渲染最后的颜色进行了填充。
将模式改为REPEAT
![](http://upload-images.jianshu.io/upload_images/3158352-7b741e2039b992bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
再将模式改为MIRROR
![](http://upload-images.jianshu.io/upload_images/3158352-3e5e9257e3564a3b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以明显看到两者的区别
或者,
我们再将y设为0到getMeasuredHeight()/4
x设为0到getMeasuredWidth()/4
REPEAT
![](http://upload-images.jianshu.io/upload_images/3158352-eff493551f6ecfee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
MIRROR
![](http://upload-images.jianshu.io/upload_images/3158352-084c24c926be1e6a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
这样一来就显示的更清楚了
REPEAT指的是单纯的重复
白黑黄-白黑黄-白黑黄-白黑黄
MIRROR则是镜像
白黑黄-黄黑白-白黑黄-黄黑白
至于前面说的两者重复中间是否有间隔
从图上好像确实看不出来
我感觉应该是因为镜像的话中间部分的颜色是一样的,因此看起来中间并没有间隔,而重复的话一般而言重复连接部分的颜色是有差别的,这样就会导致看起来在衔接部分是有间隔的。
第二个构造方法简单也试一下:
![](http://upload-images.jianshu.io/upload_images/3158352-e083303c55d5da77.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
比较简单,就是两色渐变。
使用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表示延迟重绘
如图所示:
![](http://upload-images.jianshu.io/upload_images/3158352-3c632a3bf5eacb7e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
蓝色为起点,绿色为最右侧,橙色为最左侧,白框为手机。
解释:
上面设置了渐变的长度是0到getMeasuredWidth(),那么按照我们上面的测试来看的话,应该是一个长度为getMeasuredWidth()这样的静态的渐变方案,渐变部分主要在中间,两侧的颜色依旧是设置的颜色,然后,对这个的容器整体上进行平移,即将这个渐变看做一个长方形,对这个长方形进行平移,那么就可以实现对整个渐变进行平移,上述代码在最开始运行的时候,渐变应该是从屏幕正中间开始的,然后一直将该长方形整个平移至屏幕右侧外,然后再将其平移至屏幕左侧外,再向右进行。就能实现视觉效果上的文字闪动效果。
主要就是对渐变进行了平移。
注:所有的平移的参考点都是初始点。
链接:http://www.jianshu.com/p/a9d09cb7577f