Reputation: 526
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?
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 } }
Upvotes: 2
Views: 850
Reputation: 1
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
}
}
Upvotes: -1
Reputation: 965
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)
}
Upvotes: 1
Reputation: 3351
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
Upvotes: 1