Jetpack 使用drawBehind 组成自定义阴影在 api 26 (oreo) 中无法按预期工作

问题描述 投票:0回答:1

我试图使用drawBehind和drawIntoCanvas在jetpack compose中实现自定义阴影修改器,这在api 28(pie)中工作得很好,但模糊效果在api 26(oreo)中没有按预期工作,它只在画布中绘制一个矩形但 MaskFilter 不起作用。

有什么原因吗?不支持 BlurMaskFilter 吗?

我附上了修改器函数的代码片段和相关图片。

fun Modifier.shadowCustom(
    color: Color = Color.Black,
    offsetX: Dp = 0.dp,
    offsetY: Dp = 0.dp,
    blurRadius: Dp = 0.dp,
    shapeRadius: Dp = 0.dp,
) = composed  {
    val paint: Paint = remember { Paint() }
    val blurRadiusPx = blurRadius.px(LocalDensity.current)
    val maskFilter = remember {
        BlurMaskFilter(blurRadiusPx, BlurMaskFilter.Blur.NORMAL)
    }
    drawBehind {
        drawIntoCanvas { canvas ->
            val frameworkPaint = paint.asFrameworkPaint()
            if (blurRadius != 0.dp) {
                frameworkPaint.maskFilter = maskFilter
            }
            frameworkPaint.color = color.toArgb()

            val leftPixel = offsetX.toPx()
            val topPixel = offsetY.toPx()
            val rightPixel = size.width + leftPixel
            val bottomPixel = size.height + topPixel

            if (shapeRadius > 0.dp) {
                val radiusPx = shapeRadius.toPx()
                canvas.drawRoundRect(
                    left = leftPixel,
                    top = topPixel,
                    right = rightPixel,
                    bottom = bottomPixel,
                    radiusX = radiusPx,
                    radiusY = radiusPx,
                    paint = paint,
                )
            } else {
                canvas.drawRect(
                    left = leftPixel,
                    top = topPixel,
                    right = rightPixel,
                    bottom = bottomPixel,
                    paint = paint,
                )
            }
        }
    }
}

private fun Dp.px(density: Density): Float =
    with(density) { toPx() }

android android-jetpack-compose android-jetpack
1个回答
0
投票

这是因为

BlurMaskFilter
仅适用于 Android API 28 (https://developer.android.com/topic/performance/hardware-accel#drawing-support) 的硬件加速。

您可以将应用程序或活动设置为停止硬件加速(不确定是否建议这样做,因为这可能会影响性能):

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

或者您可以尝试使用渐变方法来模拟阴影效果,如下所示(以下代码适合您的情况):

val bottomGradient = LinearGradientShader(
   from = Offset(x = 0f, y = size.height),
   to = Offset(x = 0f, y = size.height + blurRadius),
   colors = listOf(color, Color.Transparent),
)
canvas.drawRoundRect(
   left = leftPixel,
   top = size.height + topPixel,
   right = rightPixel,
   bottom = bottomPixel + blurRadius,
   radiusX = radiusPx,
   radiusY = radiusPx,
   paint = Paint().apply {
      shader = bottomGradient
   },
)

当然,您可以编辑

colorStops
和代码以匹配您想要的内容。它不能完全取代模糊效果,但它可以作为替代品,特别是如果您仅将其用于旧设备,而您将模糊用于新设备。

希望对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.