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

Posted

技术标签:

【中文标题】Android - 在 Android Pie (API 28) RadialGradient 绘制一个矩形而不是圆形【英文标题】:Android - in Android Pie (API 28) RadialGradient draws a rectangle instead of a circle 【发布时间】:2019-10-04 22:47:52 【问题描述】:

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

知道为什么它不能在 android Pie 上运行吗?

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

API 28 上的屏幕截图

Torch 视图类

类 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 - 半径 无效() 返回真

【问题讨论】:

【参考方案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)
 

【讨论】:

非常感谢,这正是我所需要的。感谢您链接问题跟踪器。【参考方案2】:

根据Official Document

PorterDuff 在 Android API 28 中已弃用

您应该将 PorterDuff 替换为 BlendMode

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

【讨论】:

Android API 28 是 Pie 而不是 Q,Q 仍处于预览阶段:/ 哦,我好像搞错了。

以上是关于Android - 在 Android Pie (API 28) RadialGradient 绘制一个矩形而不是圆形的主要内容,如果未能解决你的问题,请参考以下文章

Android Api(Okhttps)未在android 9(pie)及更高版本中调用[重复]

如何解决 GPS 在后台 android Pie 中自动关闭?

为啥 Android Studio 不会在 Android Pie (9.0) 上运行应用程序?

Android 9 Pie 崩溃 (com.google.android.gms...ClassNotFoundException)

移动: Android 9 “Pie”发布

Android Pie 无法接收百度推送通知