要让 layer-list 中某图层严格按像素高度显示,需将其包装为有明确尺寸的 drawable,最稳妥方式是用 inset 裁剪(如 android:insettop/insetbottom)或 scale 缩放,而非依赖 android:height。

layer-list 里 item 的 height 不生效?
Android 的 layer-list 本身不支持直接给 <item></item> 设固定高度,android:height 属性只在 drawable 是 bitmap 或 color 时部分生效,且受父容器约束。真正起作用的是「drawable 自身的固有尺寸」或「通过 inset / scale 等间接控制显示区域」。
怎么让 layer-list 中某个图层严格按像素高度显示?
核心思路:把目标图层包装成一个「有明确尺寸的 drawable」,再塞进 <item></item>。最稳妥的是用 inset 或 scale 做裁剪/缩放,而不是依赖 android:height。
-
inset最常用:用android:insetTop和android:insetBottom把原图“挤”出想要的高度,例如原图高 200dp,想只显示中间 48dp,就设android:insetTop="76dp" android:insetBottom="76dp" -
scale适合需要等比缩放的场景:配合android:gravity="center"和android:scaleHeight="48dp"(注意:这是 scale drawable 的属性,不是 layer-list 的)——但得把图层先定义为<scale></scale>子元素 - 别用
android:height+android:width试图“拉伸”一个shape:它只会让 shape 的绘制区域变大,但内容(如<solid></solid>)仍铺满整个区域,视觉上没变化
shape drawable 固定高度为什么总被撑开?
因为 <shape></shape> 默认是「可拉伸」的,它的尺寸由宿主 View 决定。即使你在 <item></item> 里写了 android:height="48dp",只要父 View 高度不限制(比如 wrap_content 且没其他约束),系统会忽略这个值。
- 确保外层 View 有明确高度,比如
android:layout_height="48dp";否则layer-list会按内容自适应,而 shape 没固有尺寸,结果就是 0dp 或默认最小值 - 如果必须用
wrap_content,改用<inset></inset>包裹 shape,并设android:insetTop/android:insetBottom来硬性截取高度 - 避免在
<shape></shape>里同时用<stroke></stroke>和小尺寸:描边会额外增加占用空间,实际高度 = 内容高度 + 上下 stroke 宽度
XML 里写死 dp 值,不同屏幕适配怎么办?
直接写 48dp 在多数 UI 元素中没问题,但如果是图标类图层(比如 status bar icon),要注意:layer-list 里的尺寸单位始终是 dp,系统自动换算,不用手动处理。但容易踩的坑是——误以为 android:height 是布局属性,其实它只是 hint,不参与测量流程。
- 所有
android:height/android:width在<item></item>中都只是建议值,最终以 drawable 的 intrinsic size 或容器约束为准 - 如果图层是
@drawable/ic_arrow这种 PNG,它的 intrinsic size 由图片分辨率 + density 决定,此时写android:height基本无效 - 真要跨密度严格控高,优先用
inset+ dp 值,或者改用VectorDrawable配合viewportWidth/viewportHeight
最常被忽略的一点:layer-list 本身没有 layout 行为,它只是按顺序叠一堆 drawable。所谓“固定高度”,本质是你对每个 drawable 的尺寸控制是否到位,而不是对 <item></item> 下指令。










