You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 6系统中Compose自定义阴影无法显示问题求助

解决Android 6及以下Compose自定义阴影不显示的问题

问题原因

Android 6(API 23)及更低版本的Canvas存在渲染限制:当Paint的颜色为**完全透明(alpha=0)**时,setShadowLayer的效果会被系统直接忽略。另外你代码里直接用dp作为setShadowLayer的参数也是错误的——该方法要求传入像素值,而非dp单位,这不仅会导致阴影大小在不同屏幕密度下不一致,也可能加剧旧系统的渲染异常。

修复后的代码

fun Modifier.advancedShadow(
    cornerRadius: Dp = 4.dp, // 补充原代码中缺失的cornerRadius参数
    shadowRadius: Dp = 12.dp,
    shadowYOffset: Dp = 1.dp,
    shadowColor: Color = Color.SomeColor.copy(alpha = 0.10f)
) = composed {
    val density = LocalDensity.current
    drawBehind {
        val shadowArgb = shadowColor.toArgb()
        // 用极淡的非完全透明颜色替代纯透明,避开旧系统的渲染限制
        val baseColor = Color.Black.copy(alpha = 0.01f).toArgb()
        
        drawIntoCanvas { canvas ->
            val paint = Paint()
            val frameworkPaint = paint.asFrameworkPaint()
            
            frameworkPaint.color = baseColor
            // 将dp单位正确转为像素值,适配不同屏幕密度
            with(density) {
                frameworkPaint.setShadowLayer(
                    shadowRadius.toPx(),
                    0f,
                    shadowYOffset.toPx(),
                    shadowArgb
                )
            }
            
            canvas.drawRoundRect(
                0f,
                0f,
                this.size.width,
                this.size.height,
                cornerRadius.toPx(),
                cornerRadius.toPx(),
                paint
            )
        }
    }
}

关键修改点

  • 替换完全透明色:用Color.Black.copy(alpha = 0.01f)替代原代码中的纯透明色,既不会影响视觉效果,又能让旧系统识别到Paint的存在,从而正常绘制阴影。
  • 单位正确转换:通过LocalDensity.current将dp转为像素值,符合setShadowLayer的参数要求,同时保证阴影大小在所有屏幕上一致。
  • 补充缺失参数:完善了原代码中未定义的cornerRadius参数,让函数更具复用性。

内容的提问来源于stack exchange,提问作者nilkash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 09:37:27