2

我正在尝试使用背景图像和前景图像模拟 TorchView。它在 API 27 及更低版本上运行良好,但在 API 28 上绘制一个矩形。

知道为什么它在 Android Pie 上不起作用吗?

API 27 及以下版本的屏幕截图 API 27 及以下

API 28 上的屏幕截图 API 28

火炬视图类

类 TorchView:视图,OnTouchListener {

    var mBitmapBackground:位图?=空
    var mBitmapForeground:位图?=空
    var mMask:位图?=空
    私有变量 mPosX = 0f
    私有变量 mPosY = 0f

    私有lateinit varpaintMask:油漆
    private lateinit var paintBackground: 油漆
    私有lateinit varpaintForeground:油漆

    私有变量半径 = 150


    构造函数(上下文:上下文):超级(上下文){
        在里面()
    }

    构造函数(上下文:上下文,属性:属性集):超级(上下文,属性){
        在里面()
    }


    有趣的initBitmaps(bitmapBackground:位图,bitmapForeground:位图,半径:Int){
        this.radius = 半径
        mBitmapBackground = 位图背景
        mBitmapForeground = 位图前景
        mMask = makeRadGrad()
        mPosX = (bitmapBackground.width/2 - 半径).toFloat()
        mPosY = (bitmapBackground.height/2 - 半径).toFloat()
        无效()
    }

    有趣的初始化(){
        油漆背景=油漆()

        油漆掩码 = 油漆()
        paintMask.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)

        油漆前景 = 油漆()
        paintForeground.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OVER)

        isFocusable = true
        isFocusableInTouchMode = true
        this.setOnTouchListener(这个)
    }

    公共覆盖乐趣 onDraw(canvas: Canvas) {
        超级.onDraw(画布)
        val 掩码 = mMask
        val bitmapForeground = mBitmapBackground
        val bitmapBackground = mBitmapForeground
        如果(掩码!= null && bitmapForeground != null && bitmapBackground != null){
            画布.保存()
            canvas.drawBitmap(位图背景,0f,0f,paintBackground)
            canvas.drawBitmap(掩码,mPosX,mPosY,paintMask)
            canvas.drawBitmap(位图前景,0f,0f,paintForeground)
            canvas.restore()
        }
    }

    私人乐趣 makeRadGrad(): 位图 {
        val梯度=径向梯度(
            radius.toFloat(), radius.toFloat(), radius.toFloat(), -0xff0100,
            0x00000000, android.graphics.Shader.TileMode.CLAMP
        )
        val p = 油漆()
        p.isDither = true
        p.shader = 渐变

        val bitmap = Bitmap.createBitmap(radius*2, radius*2, Config.ARGB_8888)
        val c = 画布(位图)
        c.drawCircle(radius.toFloat(), radius.toFloat(), radius.toFloat(), p)

        返回位图
    }

    覆盖 fun onTouch(v: View?, event: MotionEvent): Boolean {
        mPosX = event.x - 半径
        mPosY = event.y - 半径
        无效()
        返回真
    }
}
4

2 回答 2

1

检查这个https://issuetracker.google.com/issues/111819103

尝试这个

 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)
 }
于 2019-05-30T08:57:15.920 回答
1

根据官方文件

PorterDuff 在 Android API 28 中已弃用

你应该用BlendMode替换 PorterDuff

在此处输入图像描述

也许你应该在 Android API 28 上做一些兼容的工作

于 2019-05-29T03:47:03.480 回答