项目场景:
利用xfermode
画一个矩形和原,设置不同的xfermode
类型达到不同的效果,就是用两个图形测试下面的效果
问题描述:
如果我们这么写:
canvas.apply {
val saveLayer = saveLayer(150.dp, 50.dp, 300.dp, 200.dp, paint)
drawRect(150.dp, 100.dp, 250.dp, 200.dp, paint)
paint.xfermode = mode
drawCircle(250.dp, 100.dp, 50.dp, paint)
restoreToCount(saveLayer)
}
不管这么替换mode
,效果都和我们预想的完全不同。
private val mode = PorterDuffXfermode(PorterDuff.Mode.SRC)
效果:
private val mode = PorterDuffXfermode(PorterDuff.Mode.DST)
效果
原因分析:
这里xfermode
指的是合并两块图形及其图形所在的整块空白区域,所以这么直接用肯定有问题
再来看看官方文档怎么用:
官方文档上也是画bitmap上去。
解决方案:
把矩形画在一个bitmap上,圆画在另一个bitmap上,第一个bitmap画上去后,使用xfermode,再画第二个bitmap,这样就没有问题了。
code:
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import com.lbj23.recustomview.dp
private val BITMAP_SIZE = 150.dp.toInt()
class XFerMode(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val circleBitmap =
Bitmap.createBitmap(BITMAP_SIZE, BITMAP_SIZE, Bitmap.Config.ARGB_8888)
private val squareBitmap =
Bitmap.createBitmap(BITMAP_SIZE, BITMAP_SIZE, Bitmap.Config.ARGB_8888)
private val mode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)
init {
val canvas = Canvas(squareBitmap)
paint.color = Color.parseColor("#FFBB86FC")
canvas.drawRect(0f, 50.dp, 100.dp, 150.dp, paint)
canvas.setBitmap(circleBitmap)
paint.color = Color.parseColor("#FF03DAC5")
canvas.drawCircle(100.dp, 50.dp, 50.dp, paint)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.apply {
val saveLayer = saveLayer(150.dp, 50.dp, 300.dp, 200.dp, paint)
drawBitmap(circleBitmap, 150.dp, 50.dp, paint)
paint.xfermode = mode
drawBitmap(squareBitmap, 150.dp, 50.dp, paint)
restoreToCount(saveLayer)
}
}
}