我们已经在之前的文章:
《Android中的自绘View的那些事儿(二)之Shader渲染器和BitmapShader位图渲染器的简介》
《Android中的自绘View的那些事儿(三)之 颜色渐变渲染器:LinearGradient、RadialGradient 和SweepGradient的简介》
中介绍过渲染器基类Shader以及它五个子类中的BitmapShader、LinearGradient、RadialGradient 以及SweepGradient的使用。今天我们继续来谈谈最后一个渲染器——ComposeShader组合渲染器,它也是五个中最为复杂的渲染器
ComposeShader就是组合性渲染器,给定渲染器A、B和组合模式。当模式被应用时,它将得到一个渲染器A作为它的“DST”的结果,以及渲染器B作为它的“SRC”的结果。它有两个构造函数,我们先来看看:
ComposeShader (Shader shaderA, // 渲染器A被视为“DST”的模式,此值不能为空
Shader shaderB, // 渲染器B被看作是“SRC”的模式,此值不能为空
Xfermode mode) // 将两个渲染器组合在一起的模式,接收Xfermode对象,若为null,则默认为src_over
ComposeShader (Shader shaderA, // 渲染器A被视为“DST”的模式,此值不能为空
Shader shaderB, // 渲染器B被看作是“SRC”的模式,此值不能为空
PorterDuff.Mode mode) // 将两个渲染器组合在一起的模式,接收PorterDuff的Mode枚举,此值不能为空
在开始介绍ComposeShader前,我们先来了解上面两个构造函数中Xfermode和PorterDuff.Mode它们是什么。
Xfermode是被称为实现自定义的“transfer-modes”的绘制管道对象的基类。它的子类实现构造函数中接收模式的枚举PorterDuff 使实现预定义的绘制管道对象。它的子类一般是PorterDuffXfermode类,它可以使用图像16种组合模式规则来控制Paint对Canvas图像进行交互。要应用转换模式,可以使用Paint的setXfermode方法。
在Android SDK 目录下…\samples\android-23\legacy\ApiDemos\src\com\example\android\apis\graphics有一个Xfermodes.java类,它是一个Activity,使用它代码运行程序可见下图:
输出结果中列出了16种组合模式,也就是对应PorterDuff.Mode枚举中的16个值。好了,已经知道了Xfermode和PorterDuff怎样使用后,我们来看看ComposeShader的示例吧。
public class MyView extends View {
public MyView(Context context) {
this(context, null, 0);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.icon);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
BitmapShader bitmapShaderDst = new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
RadialGradient radialGradientSrc = new RadialGradient(width / 2, height / 2, width / 2, new int[] { Color.WHITE, Color.TRANSPARENT }, null, Shader.TileMode.CLAMP);
ComposeShader composeShader = new ComposeShader(bitmapShaderDst, radialGradientSrc, PorterDuff.Mode.MULTIPLY);
paint.setShader(composeShader);
canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
}
上面代码中,先有一个BitmapShader渲染器对象和一个RadialGradient渲染器对象,然后将其当做参数传给ComposeShader的构造函数,并使用MULTIPLY的模式