Android - 在 Android Pie (API 28) RadialGradient 中绘制矩形而不是圆形

标签 android android-canvas paint android-9.0-pie porter-duff

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

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

<表类=“s-表”> <标题> 在 API 27 及更低版本上 API 28 <正文> API 27 and below API 28

torch View 类:

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
    }
}

最佳答案

检查这个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)
 }

关于Android - 在 Android Pie (API 28) RadialGradient 中绘制矩形而不是圆形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56189189/

相关文章:

python - 如何在 QItemDelegate sizeHint() 中获取 QTreeView 单元格宽度?

java - Graphics2D DrawImage不代表图像大小

android - ArrayAdapter.createViewFromResource() 上的 NullPointerException

java - 将文件上传到 URL?

Android - 使用 C 语言的服务器代码进行服务器套接字连接?

java - 如何绘制 Path 并集的轮廓

android - 自定义 View 中的涟漪效果

Android:将 Canvas 绘制到 ImageView

c++ - 如何使用 FillRect() 绘制子窗口?

android - Google 登录 - 如何添加 Games.SCOPE_GAMES_LITE?