在Android中可以使用Shader对象指定的渲染效果来填充图形。Shader本身是一个抽象类,提供如下实现类:
BitmapShader:使用位图平铺的渲染效果
LinearGradient:使用线性渐变来填充图形
RadialGradient:使用圆形渐变来填充图形
SweepGradient:使用角度渐变来填充图形
ComposeShader:使用组合渲染来填充图形
使用时可以通过paint.setShader(Shader shader);来实现一些渲染效果。
定义了3种平铺模式:
static final Shader.TileMode CLAMP: 边缘拉伸
static final Shader.TileMode MIRROR:在水平方向和垂直方向交替景象, 两个相邻图像间没有缝隙
Static final Shader.TillMode REPETA:在水平方向和垂直方向重复摆放,两个相邻图像间有缝隙
BitmapShader位图渲染
public BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)
调用这个方法来产生一个画有一个位图的渲染器(Shader)。
bitmap:在渲染器内使用的位图
tileX :在位图上X方向渲染器平铺模式
tileY:在位图上Y方向渲染器平铺模式
LinearGradient线性渲染
public LinearGradient(floatx0, float y0, float x1, float y1, int[] colors, float[] positions,Shader.TileMode tile)
参数:
float x0: 渐变起始点x坐标
float y0:渐变起始点y坐标
float x1:渐变结束点x坐标
float y1:渐变结束点y坐标
int[] colors:颜色 的int 数组
float[] positions: 相对位置的颜色数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布
Shader.TileMode tile: 渲染器平铺模式
public LinearGradient(floatx0, float y0, float x1, float y1, int color0, int color1,Shader.TileMode tile)
float x0: 渐变起始点x坐标
float y0:渐变起始点y坐标
float x1:渐变结束点x坐标
float y1:渐变结束点y坐标
int color0: 起始渐变色
int color1: 结束渐变色
Shader.TileMode tile: 渲染器平铺模式
RadialGradient环形渲染
public RadialGradient(float x, float y, floatradius, int[] colors, float[] positions,Shader.TileMode tile)
float x: 圆心X坐标
float y: 圆心Y坐标
float radius: 半径
int[] colors: 渲染颜色数组
floate[] positions: 相对位置数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布
Shader.TileMode tile:渲染器平铺模式
public RadialGradient(float x, float y, floatradius, int color0, int color1,Shader.TileMode tile)
float x: 圆心X坐标
float y: 圆心Y坐标
float radius: 半径
int color0: 圆心颜色
int color1: 圆边缘颜色
Shader.TileMode tile:渲染器平铺模式
SweepGradient 扫描/梯度渲染
public SweepGradient(floatcx, float cy, int[] colors, float[] positions)
cx:渲染中心点x 坐标
cy:渲染中心y 点坐标
colors:围绕中心渲染的颜色数组,至少要有两种颜色值
positions:相对位置的颜色数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布
public SweepGradient(floatcx, float cy, int color0, int color1)
cx:渲染中心点x 坐标
cy:渲染中心y 点坐标
color0:起始渲染颜色
color1:结束渲染颜色
ComposeShader组合渲染
public ComposeShader(Shader shaderA,Shader shaderB, Xfermode mode)
shaderA:渲染器A,Shader及其子类对象
shaderB: 渲染器B,Shader及其子类对象
mode:两种渲染器组合的模式,Xfermode对象
public ComposeShader(Shader shaderA,Shader shaderB, PorterDuff.Mode mode)
shaderA:渲染器A,Shader及其子类对象
shaderB: 渲染器B,Shader及其子类对象
mode:两种渲染器组合的模式, ProterDuff.Mode对象
PorterDuff.Mode为枚举类,一共有16个枚举值:
1.PorterDuff.Mode.CLEAR 所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC 显示上层绘制图片
3.PorterDuff.Mode.DST 显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR 异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN 取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN 取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY 取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN 取两图层全部区域,交集部分变为透明色
示例代码:
public class ShaderTest extends Activity implements OnClickListener{
private Shader[] shaders = new Shader[5];// 声明位图渲染对象
private int[] colors;// 声明颜色数组
MyView myView;// 自定义视图类
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myView = (MyView)findViewById(R.id.my_view);
// 获得Bitmap实例
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.water);
// 设置渐变的颜色组,也就是按红、绿、蓝的方式渐变
colors = new int[] { Color.RED, Color.GREEN, Color.BLUE };
// 实例化BitmapShader,x坐标方向重复图形,y坐标方向镜像图形
shaders[0] = new BitmapShader(bm, TileMode.REPEAT, TileMode.MIRROR);
// 实例化LinearGradient
shaders[1] = new LinearGradient(0, 0, 100, 100, colors, null, TileMode.REPEAT);
// 实例化RadialGradient
shaders[2] = new RadialGradient(100, 100, 80, colors, null, TileMode.REPEAT);
// 实例化SweepGradient
shaders[3] = new SweepGradient(160, 160, colors, null);
// 实例化ComposeShader
shaders[4] = new ComposeShader(shaders[1], shaders[2], PorterDuff.Mode.DARKEN);
Button bn1 = (Button)findViewById(R.id.bn1);
Button bn2 = (Button)findViewById(R.id.bn2);
Button bn3 = (Button)findViewById(R.id.bn3);
Button bn4 = (Button)findViewById(R.id.bn4);
Button bn5 = (Button)findViewById(R.id.bn5);
bn1.setOnClickListener(this);
bn2.setOnClickListener(this);
bn3.setOnClickListener(this);
bn4.setOnClickListener(this);
bn5.setOnClickListener(this);
}
@Override
public void onClick(View source){
switch(source.getId()){
case R.id.bn1:
myView.paint.setShader(shaders[0]);
break;
case R.id.bn2:
myView.paint.setShader(shaders[1]);
break;
case R.id.bn3:
myView.paint.setShader(shaders[2]);
break;
case R.id.bn4:
myView.paint.setShader(shaders[3]);
break;
case R.id.bn5:
myView.paint.setShader(shaders[4]);
break;
}
myView.invalidate();// 重绘界面
}
}