Shader之LinearGradient
- 通过LinearGradient实现线性渐变效果
- 构造函数:
1.指定两种颜色之间的渐变
//(x0, y0)渐变的起始点坐标,(x1,y1)渐变的终点坐标
//color0起始颜色
//color1终止颜色
//tile:用于指定当控件区域大于指定的渐变区域时的填充模式
public LinearGradient(float x0, float y0, flloat x1, float y1, int color0, int color1, TileMode tile);
2.指定多种颜色之间的渐变:
//(x0, y0)渐变的起始点 (x1, y1)渐变的终止点
//colors[]用于指定渐变颜色的数组,颜色值必须使用十六进制的形式
//position[]与渐变颜色相对应,取值是0~1的Float类型的数据,表示每种颜色在整条渐变线中的百分比位置
public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[], TileMode tile);
eg: 双色渐变
private Paint paint;
public JianBian(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
setLayerType(LAYER_TYPE_SOFTWARE ,null);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setShader(new LinearGradient(0, getHeight()/2, getWidth(), getHeight()/2, 0xffff0000, 0xff00ff00, Shader.TileMode.CLAMP));
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
eg: 多色渐变
private Paint paint;
public JianBian(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
setLayerType(LAYER_TYPE_SOFTWARE ,null);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设定颜色数组
int[] colors = {0xffff0000, 0xff00ff00, 0xff0000ff,0xffffff00, 0xff00ffff};
//设定进度数组
float[] pos = {0f, 0.2f, 0.4f, 0.6f, 1.0f};
paint.setShader(new LinearGradient(0, getHeight()/2, getWidth(), getHeight()/2, colors, pos, Shader.TileMode.CLAMP));
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
- 注意:
- colors和pos数组的item的数目一定要相等,必须指定每个颜色值的位置。
2.填充模式:
-
这里的填充模式和设置Shader的填充模式的不同之处在于,他的模式只有一个,则说明X轴和Y轴共用一个TileMode,下面是三种填充效果图:
-
REPEAT
-
MIRROR
-
CLAMP
Shader填充与显示区域:
- 首先明确一点Shader的布局与显示是分离的,所以Shadre总是从控件的左上角开始布局,如果单张图片无法覆盖整个图片那么就使用TileMode重复模式来填充空白,而cnavas.draw只表示哪一部分区域被表示出来
eg: 文字渐变
private Paint paint;
public JianBianWenZi(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(LAYER_TYPE_SOFTWARE, null);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int[] colors = {0xffff0000, 0xff00ff00, 0xff0000ff,0xffffff00, 0xff00ffff};
float[] pos = {0f, 0.2f, 0.4f, 0.6f, 1.0f};
paint.setShader(new LinearGradient(0, 0, getWidth()/2, getHeight()/2, colors, pos, Shader.TileMode.MIRROR));
paint.setTextSize(120);
canvas.drawText("感谢学习WJX的Blog",0, 200, paint);
}
Shader之RadialGradient(放射渐变)
- 这个渐变效果会像放射源一样,从一个点向外发散,从一种颜色变成另一种颜色
双色渐变:
//centerX:渐变中心点X的坐标
//centerY:渐变中心点Y的坐标
//radius:渐变半径
//centerColor:渐变的起始颜色,渐变中心点的颜色,必须为8位颜色值,透明值不可以省略
//edgeColor:渐变结束颜色,渐变边缘的颜色
//tileMode:覆盖效果
RadialGradient(float centerX, float centerY, float radius, int centerColor, int edgeColor, Shader.TileMode tileMode);
eg:
private Paint paint;
private RadialGradient radialGradient;
private int radius;
public RadialGRadientView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
setLayerType(LAYER_TYPE_SOFTWARE, null);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(radialGradient == null){
radius = getWidth() / 2;
radialGradient = new RadialGradient(getWidth()/ 2, getHeight()/ 2, radius, 0xffff0000,0xff00ff00, Shader.TileMode.REPEAT);
paint.setShader(radialGradient);
}
canvas.drawCircle(getWidth()/2, getHeight()/2, radius, paint);
}
多色渐变:
//colors[]: 渐变颜色列表
//stops:表示每种颜色所在位置的百分点,取值范围为0~1,数量必须与colors数组保持一致,如果超过覆盖 范围的部分,则按照覆盖规则进行覆盖,但是效果有时不可控,所以建议使用stops的范围是0~1的范围
RadialGradient(float centerX, float centerY, float radius, int[] colors, float[] stops, Shader.TileMode tileMode);
private Paint paint;
private RadialGradient radialGradient;
private int radius;
public RadialGRadientView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
setLayerType(LAYER_TYPE_SOFTWARE, null);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(radialGradient == null){
radius = getWidth() / 2;
int[] colors = {0xffff0000, 0xff00ff00, 0xff0000ff,0xffffff00, 0xff00ffff};
float[] stops = {0f, 0.2f, 0.4f, 0.6f, 1.0f};
radialGradient = new RadialGradient(getWidth()/ 2, getHeight()/ 2, radius, colors, stops, Shader.TileMode.REPEAT);
paint.setShader(radialGradient);
}
canvas.drawCircle(getWidth()/2, getHeight()/2, radius, paint);
}