命运就像自己的掌纹,虽然弯弯曲曲,却永远掌握在自己手中。
本讲内容:Xfermode 图像混合模式类(和ColorFilter有点相似的方法)
Xfermode 类的三个子类分别是AvoidXfermode, PixelXorXfermode和PorterDuffXfermode
AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。
PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素XOR操作。
PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的18条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。
要应用转换模式,可以使用setXferMode方法,如下所示:
AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); borderPen.setXfermode(avoid);
一、AvoidXfermode类(只有一个含参的构造方法)
<span style="font-size:18px;">AvoidXfermode(int opColor, int tolerance, AvoidXfermode.Mode mode)</span>
第一个opColor表示一个16进制的可以带透明通道的颜色值例如0x12345678,第二个参数tolerance表示容差值,最后一个参数表示AvoidXfermode的具体模式,其可选值只有两个:AvoidXfermode.Mode.TARGET或者 AvoidXfermode.Mode.AVOID
二者区别:
1、AvoidXfermode.Mode.TARGET:在该模式下Android会判断画布上的颜色是否会有与pColor一样的颜色,如果有,则把该区域“染”上一层我们画笔定义的颜色,否则不“染”色
2、而AVOID是在该模式下Android会判断画布上的颜色是否会有与pColor不一样的颜色,……
示例一:
注意:因为这个AvoidXfermode类不支持硬件加速在API 16已经过时(会出现图一效果),如果要使用,必须在应用或手机设置中关闭硬件加速在应用中我们可以通过在AndroidManifest.xml文件中设置application节点下的android:hardwareAccelerated属性为false来关闭硬件加速:
<application
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
<activity
android:name="com.aigestudio.customviewdemo.activities.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
在AndroidManifest.xml文件中关闭硬件加速那么我们整个应用都将不支持硬件加速,这显然是不科学的,如果可以只针对某个View关闭硬件加速那岂不是很好么?当然,Android也给我们提供了这样的功能,我们可以在View中通过
setLayerType(LAYER_TYPE_SOFTWARE, null);
下面是自定义CustomTitleView.java文件:
public class CustomView extends View {
private Paint mPaint;// 画笔
private Context mContext;// 上下文环境引用
private Bitmap bitmap;// 位图
private AvoidXfermode avoidXfermode;// AV模式
private int x,y,w,h;// 位图绘制时左上角的起点坐标
public CustomView(Context context) {
super(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
initPaint();// 初始化画笔
initRes(context);//初始化资源
}
//初始化资源
private void initRes(Context context) {
// 获取位图
bitmap=BitmapFactory.decodeResource(context.getResources(), R.drawable.p);
/*
* 计算位图绘制时左上角的坐标使其位于屏幕中心
* 屏幕坐标x轴向左偏移位图一半的宽度
* 屏幕坐标y轴向上偏移位图一半的高度
*/
x=MeasureUtil.getScreenSize((Activity)mContext)[0]/2-bitmap.getWidth()/2;
y = MeasureUtil.getScreenSize((Activity) mContext)[1] / 2 - bitmap.getHeight() / 2;
w = MeasureUtil.getScreenSize((Activity) mContext)[0] / 2 + bitmap.getWidth() / 2;
h = MeasureUtil.getScreenSize((Activity) mContext)[1] / 2 + bitmap.getHeight() / 2;
}
// 初始化画笔
private void initPaint() {
// 实例化画笔并打开抗锯齿
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//当画布中有跟0XFFFFFFFF(白)色一样的地方时候才“染”色
//avoidXfermode = new AvoidXfermode(0XFFFFFFFF, 0, AvoidXfermode.Mode.TARGET);
//当画布中有跟0XFFFFFFFF色相差很100内(有点接近)的地方时候才“染”色
avoidXfermode = new AvoidXfermode(0XFFFFFFFF, 100, AvoidXfermode.Mode.TARGET);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制位图 从资源获取一个Bitmap绘制在画布上
canvas.drawBitmap(bitmap, x, y,mPaint);
// “染”什么色是由我们自己决定的
mPaint.setARGB(255, 215, 53, 243);
// 设置AV模式
mPaint.setXfermode(avoidXfermode);
// 画一个位图大小一样的矩形
canvas.drawRect(x, y, w, h, mPaint);
}
}
二、PixelXorXfermode类(与AvoidXfermode一样也在API 16过时了,只有一个含参的构造方法)
PixelXorXfermode(int opColor)
该类的计算实现公式是:op ^ src ^ dst,像素色值的按位异或运算
Take your time and enjoy it 路过的、学习过的请留个言,顶个呗~~