layer-list中不能直接用android:drawable引用位图,须用包裹;需显式设item宽高并配gravity="center"实现居中;图标应优先用@mipmap;避免xml嵌套过深,超三层易崩溃。

layer-list 里用 android:drawable 引图片会失败
直接写 android:drawable="@drawable/icon" 在 <item></item> 里,编译不报错但运行时可能黑块、拉伸异常,甚至崩溃(尤其在旧 Android 版本)。这不是资源没找到,而是 android:drawable 属性只被部分系统版本支持,且仅适用于纯颜色或 shape,**不兼容位图资源**。
正确做法是用 <bitmap></bitmap> 包一层:
<item> <bitmap android:src="@drawable/icon" /> </item>
-
android:src是<bitmap></bitmap>的标准属性,所有 API 级别都稳定支持 - 如果要缩放/平铺,加
android:gravity或android:tileMode到<bitmap></bitmap>内 - 避免在
<item></item>上直接设android:width/android:height:它们对位图无效,得靠<bitmap></bitmap>的android:gravity控制显示区域
想让图片居中不拉伸,android:gravity="center" 不起作用?
常见现象:加了 android:gravity="center" 还是铺满整个 layer-list 区域。根本原因是——这个属性只在 <bitmap></bitmap> 有明确尺寸约束时才生效,而默认情况下 <bitmap></bitmap> 会撑满父 <item></item> 宽高。
解决路径只有两条:
- 给外层
<item></item>显式设android:width和android:height(单位必须是dp),再配android:gravity="center" - 改用
<vector></vector>或<shape></shape>替代位图——它们天生响应gravity,且无像素缩放问题
例如固定 24dp × 24dp 区域居中显示:
<item android:width="24dp" android:height="24dp"> <bitmap android:src="@drawable/ic_check" android:gravity="center" /> </item>
使用 @mipmap 而不是 @drawable 引用图标
很多人图省事全用 @drawable,但在 layer-list 中引用启动图标、状态栏图标这类资源时,@mipmap 才是正确选择。原因很实际:
-
@mipmap目录下资源会被系统按屏幕密度原样保留,不会被 aapt2 缩放或优化掉 -
@drawable下的图片在构建时可能被自动适配(比如 xxhdpi 资源被 downscale 到 mdpi),导致 layer-list 里尺寸错乱 - Android Studio 新建 launcher icon 默认放
mipmap,直接引用更安全
错误写法:android:src="@drawable/ic_launcher"
正确写法:android:src="@mipmap/ic_launcher"
XML drawable 嵌套过深导致 inflate 失败
layer-list 套 layer-list,里面再塞 bitmap、selector、inset……到第四五层时,某些低端机型(尤其是 Android 5.0–6.0)会直接抛 Resources$NotFoundException 或 StackOverflowError,日志里看不到具体哪一层崩,只显示 “Failed to inflate”。
这不是语法错,是系统解析 XML 的栈深度限制。规避方法很直接:
- 把深层嵌套拆成独立 XML 文件,用
@drawable/xxx引用,而不是全堆在一个文件里 - 检查是否真需要多层叠加——很多效果用
<inset></inset>+<scale></scale>就能替代两层layer-list - 在
build.gradle里加android.enableAapt2=false可缓解(但只是临时手段,AAPT2 是趋势)
真正难处理的是动态生成 layer-list 的场景:这时候 XML 已经不是首选,该切到 LayerDrawable 代码构造。








