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
相关产品推荐
相关产品推荐

