I'm trying to simulate a TorchView with a background image and a foreground image. It works well on API 27 and below but draw a rectangle on API 28.
Any idea why it doesn't work on Android Pie ?
Screenshot on API 27 and below

Torch View class
class TorchView : View, OnTouchListener {
var mBitmapBackground: Bitmap? = null
var mBitmapForeground: Bitmap? = null
var mMask: Bitmap? = null
private var mPosX = 0f
private var mPosY = 0f
private lateinit var paintMask: Paint
private lateinit var paintBackground: Paint
private lateinit var paintForeground: Paint
private var radius = 150
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
fun initBitmaps(bitmapBackground: Bitmap, bitmapForeground: Bitmap, radius: Int){
this.radius = radius
mBitmapBackground = bitmapBackground
mBitmapForeground = bitmapForeground
mMask = makeRadGrad()
mPosX = (bitmapBackground.width/2 - radius).toFloat()
mPosY = (bitmapBackground.height/2 - radius).toFloat()
invalidate()
}
fun init() {
paintBackground = Paint()
paintMask = Paint()
paintMask.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
paintForeground = Paint()
paintForeground.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)
isFocusable = true
isFocusableInTouchMode = true
this.setOnTouchListener(this)
}
public override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val mask = mMask
val bitmapForeground = mBitmapBackground
val bitmapBackground = mBitmapForeground
if(mask != null && bitmapForeground != null && bitmapBackground != null){
canvas.save()
canvas.drawBitmap(bitmapBackground, 0f, 0f, paintBackground)
canvas.drawBitmap(mask, mPosX, mPosY, paintMask)
canvas.drawBitmap(bitmapForeground, 0f, 0f, paintForeground)
canvas.restore()
}
}
private fun makeRadGrad(): Bitmap {
val gradient = RadialGradient(
radius.toFloat(), radius.toFloat(), radius.toFloat(), -0xff0100,
0x00000000, android.graphics.Shader.TileMode.CLAMP
)
val p = Paint()
p.isDither = true
p.shader = gradient
val bitmap = Bitmap.createBitmap(radius*2, radius*2, Config.ARGB_8888)
val c = Canvas(bitmap)
c.drawCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), p)
return bitmap
}
override fun onTouch(v: View?, event: MotionEvent): Boolean {
mPosX = event.x - radius
mPosY = event.y - radius
invalidate()
return true
}
}
According to the Official Document
PorterDuff was deprecated in Android API 28
You should replace PorterDuff with BlendMode
Maybe you should do some compatible work on Android API 28
check this https://issuetracker.google.com/issues/111819103
try this
public override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val mask = mMask
val bitmapForeground = mBitmapBackground
val bitmapBackground = mBitmapForeground
if(mask != null && bitmapForeground != null && bitmapBackground != null){
canvas.save()
canvas.drawBitmap(bitmapBackground, 0f, 0f, paintBackground)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
makeRadGradP(canvas, bitmapForeground)
} else {
canvas.drawBitmap(mask, mPosX, mPosY, paintMask)
canvas.drawBitmap(bitmapForeground, 0f, 0f, paintForeground)
}
canvas.restore()
}
}
private fun makeRadGradP(canvas: Canvas, bm: Bitmap) {
val paint = Paint()
paint.style = Paint.Style.FILL
val shader = BitmapShader(bm, TileMode.CLAMP, TileMode.CLAMP)
paint.shader = shader
val corners = Path()
corners.addCircle(mPosX + radius, mPosY + radius, radius.toFloat(), Path.Direction.CW)
canvas.drawPath(corners, paint)
val gradient = RadialGradient(
mPosX + radius, mPosY + radius, radius.toFloat(), 0x00000000,
Color.parseColor("#df000000"), TileMode.CLAMP
)
val p = Paint()
p.isDither = true
p.shader = gradient
canvas.drawCircle(mPosX + radius, mPosY + radius, radius.toFloat(), p)
}
User contributions licensed under CC BY-SA 3.0