Android layer-list实现阴影 XML绘制带阴影的背景

1次阅读

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

Android layer-list实现阴影 XML绘制带阴影的背景

layer-list 里 shadow 不能靠 android:shadowColor

Android 的 layer-list 本身不支持阴影属性,android:shadowColorandroid:shadowDx 这些只在 TextView 或自定义 Paint 中生效,写在 shapeitem 里完全被忽略。你看到阴影没出来,不是写法不对,是这条路根本走不通。

用 offset + 多层 shape 模拟阴影最可靠

真正在 XML 里做出阴影效果,本质是「画一个偏移的深色块,再叠上主体」。这是兼容性最好、控制最细的方式,适用于所有 API 级别。

  • 底层放一个比主体宽高各多 dp 的深灰色 shape,用 android:topandroid: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 里无法实现——要么切图,要么用 RenderScriptBlurView 动态绘制,要么升级到 Compose 用 BoxShadow

这点最容易被忽略:花半天调 alphaoffset,以为能“接近”模糊效果,其实只是换了种硬边形态。该换方案时就换,别卡在 XML 里死磕。

text=ZqhQzanResources