xml中layer-list无法使用android:shadowcolor等属性实现阴影,可靠方案是用多层shape偏移模拟:底层深色shape偏移2dp,上层主体shape居中,均设gravity="top|left";api 21+可用elevation,但不支持模糊效果。

layer-list 里 shadow 不能靠 android:shadowColor
Android 的 layer-list 本身不支持阴影属性,android:shadowColor、android:shadowDx 这些只在 TextView 或自定义 Paint 中生效,写在 shape 或 item 里完全被忽略。你看到阴影没出来,不是写法不对,是这条路根本走不通。
用 offset + 多层 shape 模拟阴影最可靠
真正在 XML 里做出阴影效果,本质是「画一个偏移的深色块,再叠上主体」。这是兼容性最好、控制最细的方式,适用于所有 API 级别。
- 底层放一个比主体宽高各多
dp的深灰色shape,用android:top和android:left向右下偏移,模拟阴影落点 - 上层放实际背景(比如圆角矩形),尺寸按正常内容区域定
- 两层
shape都必须设android:gravity="top|left",否则偏移失效 - 阴影颜色建议用半透明白色或灰色(如
#20000000),太黑会像边框,太淡看不出
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:top="2dp"
android:left="2dp">
<shape android:shape="rectangle">
<solid android:color="#20000000" />
<corners android:radius="8dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="8dp" />
</shape>
</item>
</layer-list>
用 elevation 更简单,但只在 API 21+ 生效
如果你只要卡片式阴影,且最低支持 Android 5.0(API 21),直接给 View 设 android:elevation 是最省事的——系统自动渲染真实阴影,响应点击抬升,还能和 translationZ 配合动画。
-
elevation值单位是dp,但实际阴影扩散范围受系统渲染影响,1dp 不等于 1px 阴影宽度 - 必须配合
android:outlineProvider="bounds"(默认已设)才能让阴影贴合背景形状,否则是矩形轮廓 - 如果背景用了
layer-list且含透明区域,elevation 阴影可能漏出,此时仍得回退到多层 shape 方案
阴影边缘模糊?XML 里做不到,别硬刚
原生 layer-list 所有绘制都是硬边,没有高斯模糊、渐变透明等能力。你看到某些设计稿里柔和的阴影,在 XML 里无法实现——要么切图,要么用 RenderScript 或 BlurView 动态绘制,要么升级到 Compose 用 BoxShadow。
这点最容易被忽略:花半天调 alpha 和 offset,以为能“接近”模糊效果,其实只是换了种硬边形态。该换方案时就换,别卡在 XML 里死磕。










