Jetpack Compose中Surface如何实现仅显示三边(无顶部)的自定义阴影

方案1:裁剪顶部阴影(最简单实现)
该方案不需要修改原有组件的逻辑,仅通过外层容器裁剪即可实现需求,适配成本极低:
Box( modifier = Modifier .fillMaxWidth() // 顶部padding值和Surface的elevation保持一致即可 .padding(top = 12.dp) .clipToBounds() ) { Surface( modifier = Modifier .fillMaxWidth() // 向上偏移同等距离,抵消父布局padding的影响,让组件回到原位置 .offset(y = (-12).dp), shape = RectangleShape, color = toolBarBackground(), elevation = 12.dp, ) { // 原有Toolbar的实现逻辑 ... } }
原理说明:Surface的elevation阴影会向组件四周外扩散,向上偏移后顶部阴影会超出父容器的顶部边界,父容器开启裁剪后直接裁掉这部分阴影,左右和底部的阴影不受影响,组件本身的显示位置也不会发生变化。
方案2:自定义绘制阴影(灵活可控)
如果需要更精细地调整三个方向的阴影参数,可以直接手动绘制阴影,不依赖Surface自带的elevation属性:
Surface( shape = RectangleShape, color = toolBarBackground(), modifier = Modifier .fillMaxWidth() .drawBehind { val shadowWidth = 12.dp.toPx() val shadowColor = Color.Black.copy(alpha = 0.2f) // 绘制底部阴影 drawRect( color = shadowColor, topLeft = Offset(0f, size.height), size = size.copy(height = shadowWidth), blur = shadowWidth ) // 绘制左侧阴影 drawRect( color = shadowColor, topLeft = Offset(-shadowWidth, 0f), size = size.copy(width = shadowWidth), blur = shadowWidth ) // 绘制右侧阴影 drawRect( color = shadowColor, topLeft = Offset(size.width, 0f), size = size.copy(width = shadowWidth), blur = shadowWidth ) } ) { // 原有Toolbar的实现逻辑 ... }
注意:如果需要兼容Android 12以下系统,可将blur参数替换为渐变效果实现模糊阴影,无需依赖系统的模糊API。
你之前的自定义Shape方案失效的原因是:将路径的顶部边界设置到了负坐标区域,会导致Surface测量布局尺寸时将这部分超出区域也计算在内,最终出现组件尺寸异常的问题。
内容的提问来源于stack exchange,提问作者Ebin Joy
相关产品推荐
相关产品推荐

