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

Jetpack Compose如何实现支持XY偏移、模糊等参数的自定义阴影?

Jetpack Compose 自定义阴影实现方案

可以通过Canvas实现完全自定义的阴影效果,以下提供的通用Modifier扩展方案适用于Card、Box、Column、Row等所有Compose布局组件,支持自由配置X偏移、Y偏移、模糊值、颜色、透明度、圆角等参数。


自定义阴影Modifier代码

import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.RoundRect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

fun Modifier.customShadow(
    // 阴影X轴偏移:正数向右,负数向左
    offsetX: Dp = 0.dp,
    // 阴影Y轴偏移:正数向下,负数向上
    offsetY: Dp = 0.dp,
    // 阴影模糊半径:数值越大阴影越柔和
    blurRadius: Dp = 0.dp,
    // 阴影颜色:可通过copy(alpha = x)调整透明度
    shadowColor: Color = Color.Black.copy(alpha = 0.1f),
    // 阴影圆角:和组件本身的圆角保持一致即可
    cornerRadius: Dp = 0.dp
) = this.then(
    Modifier.drawBehind {
        // 构建阴影的路径
        val shadowPath = Path().apply {
            addRoundRect(
                RoundRect(
                    left = offsetX.toPx(),
                    top = offsetY.toPx(),
                    right = size.width + offsetX.toPx(),
                    bottom = size.height + offsetY.toPx(),
                    cornerRadius = CornerRadius(cornerRadius.toPx())
                )
            )
        }

        drawIntoCanvas { canvas ->
            val shadowPaint = Paint()
            shadowPaint.asFrameworkPaint().apply {
                isAntiAlias = true
                color = shadowColor.toArgb()
                // 设置模糊效果
                maskFilter = android.graphics.MaskFilter.createBlurMaskFilter(
                    blurRadius.toPx(),
                    android.graphics.BlurMaskFilter.Blur.NORMAL
                )
            }
            // 先绘制阴影,再绘制组件本身内容
            canvas.drawPath(shadowPath, shadowPaint)
        }
    }
)

使用示例

所有布局组件直接链式调用该Modifier即可生效,示例如下:

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

// 1. 给Card添加自定义阴影
Card(
    modifier = Modifier
        .customShadow(
            offsetX = 4.dp,
            offsetY = 6.dp,
            blurRadius = 12.dp,
            shadowColor = Color.Gray.copy(alpha = 0.3f),
            cornerRadius = 16.dp
        ),
    shape = RoundedCornerShape(16.dp)
) {
    Text(text = "带自定义阴影的Card", modifier = Modifier.padding(16.dp))
}

// 2. 给Box添加自定义阴影
Box(
    modifier = Modifier
        .size(100.dp)
        .customShadow(
            offsetX = (-2).dp,
            offsetY = (-2).dp,
            blurRadius = 8.dp,
            shadowColor = Color.Blue.copy(alpha = 0.2f)
        )
        .background(Color.White)
)

// 3. 给Column添加自定义阴影
Column(
    modifier = Modifier
        .customShadow(
            offsetX = 2.dp,
            offsetY = 2.dp,
            blurRadius = 4.dp,
            shadowColor = Color.Black.copy(alpha = 0.15f)
        )
        .background(Color.White)
        .padding(16.dp)
) {
    Text(text = "列表项1")
    Text(text = "列表项2")
    Text(text = "列表项3")
}

适配说明

  • 如果需要给直角组件添加阴影,将cornerRadius参数设置为0.dp即可
  • 如果需要适配圆形、切角等特殊形状的组件,只需修改customShadow方法中shadowPath的绘制逻辑匹配组件形状即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:24:03