说起Xfermode,网上随便一搜就有很多解释。诸多解释中都会包含这张图,看的确实明白,用起来的时候才知到有多坑。

主要多亏了PorterDuffXferMode不正确的真正原因PorterDuffXferMode深入试验)这篇文章,才不至于摔死在坑中。
可以解决的问题
如果你在使用XferMode
的过程中遇到了 参数设置无效,不显示图案,显示图案不正确,显示图案有时候正确有时候不正确,显示图案和参数不符...等一系列花里胡哨的问题时候,不妨看看本文。
结论
先说结论,PorterDuffXferMode的正常使用需满足以下条件:
- 关闭硬件加速
- 背景色为透明
-
必须使用bitmap绘制!!(这里解释了为什么有的同学用
drawRect
,drwaCicle
bug一片的问题😖 -
上图中
xferMode
的所有效果都是在两个bitmap重合的区域发生,所以一般情况下,两个bitmap的位置和大小尽量保持一致。
测试代码
若是信不过这个结论,在下有代码一份可供参考使用:
class XFerModeView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr){
private val paint:Paint = Paint()
//修改此处xfemode的值,即可看到相应效果
private val xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
private val mSrcBitmap: Bitmap = Bitmap.createBitmap(800,800, Bitmap.Config.ARGB_8888)
private val mSrcCanvas = Canvas(mSrcBitmap);
private val mDstBitmap: Bitmap = Bitmap.createBitmap(800,800, Bitmap.Config.ARGB_8888)
private val mDstCanvas = Canvas(mDstBitmap)
init {
paint.apply {
color = Color.YELLOW
style = Paint.Style.FILL
}
setLayerType(View.LAYER_TYPE_SOFTWARE, null)//关闭硬件加速
mDstCanvas.drawCircle(200f,200f,200f,paint)
paint.color = Color.BLUE
mSrcCanvas.drawRect(200f,200f,500f,500f,paint)
}
override fun onDraw(canvas: Canvas) {
canvas.drawBitmap(mDstBitmap,0f,0f,paint)
paint.xfermode = xfermode
canvas.drawBitmap(mSrcBitmap,0f,0f,paint)
}
}
任意修改xfermode
的值,可查看效果,所显示于示例一致。
细节
具体的踩坑细节可以看PorterDuffXferMode不正确的真正原因PorterDuffXferMode深入试验)这篇文章,向英勇的排雷者致敬😂
网友评论