android:gravity在layer-list的item中仅影响drawable内容在其分配区域内的对齐,而非item相对于layer-list的整体位置;需配合android:width/android:height和android:right/android:bottom等负边距实现精确定位。

layer-list 中 android:gravity 为什么没效果?
因为 android:gravity 在 <item></item> 里只对「自身 drawable 的内容」起作用,不是控制 item 相对于 layer-list 整体的定位。很多人误以为它能像 RelativeLayout 那样“把这张图钉在右下角”,实际它只是调整 drawable 内部像素(比如一张 PNG)在其分配到的矩形区域里的摆放方式。
常见错误现象:
– 设置了 android:gravity="bottom|end",但图层还是居中
– 多个 <item></item> 叠在一起,位置始终不变
– 换了不同尺寸 drawable 后对齐行为突然异常
- 真正决定 item 位置的是它「占用的空间大小」:如果没设
android:width/android:height,系统默认按 drawable 原尺寸撑开,此时gravity几乎不可见 - 只有当 item 分配到的区域 > drawable 实际尺寸时,
gravity才有表现空间(比如给一个 24dp×24dp 的图标分配了 48dp×48dp 区域) - 注意:矢量图(
vector)或带 intrinsic size 的 drawable 行为更隐蔽,容易误判
想让 item 精确停在右下角,该填哪些参数?
必须同时约束尺寸 + 明确偏移,靠 gravity 单独做不到。核心思路是:用 android:width 和 android:height 固定 item 占位大小,再用 android:top/android:right 等负边距把它“推”到角落。
使用场景:带徽标(badge)的图标、右上角关闭按钮、底部阴影条等需要像素级定位的叠加层
- 先写死 item 尺寸,例如
android:width="20dp"+android:height="20dp" - 再用负 margin 定位:比如右下角就加
android:right="8dp"+android:bottom="8dp" - 若需适配不同屏幕密度,优先用
dp,避免直接写px;矢量图建议统一用android:viewportWidth/android:viewportHeight控制基准 - 注意:layer-list 自身没有 padding,所有偏移都相对于父容器边界计算
<item android:width="24dp" android:height="24dp"
android:right="12dp" android:bottom="12dp">
<bitmap android:src="@drawable/ic_close" />
</item>
gravity 和 inset、padding 混用时谁优先级高?
android:gravity 作用于 drawable 内容,android:inset 或 android:padding(在 <bitmap></bitmap> 等子标签里)作用于 drawable 边界,二者不冲突但容易互相掩盖效果。
性能影响很小,但兼容性要注意:Android 4.0+ 对 inset 支持稳定,而 padding 在 <bitmap></bitmap> 里从 API 23 才完全可靠
- 如果目标是“图标整体往右挪 4dp”,用
android:right="4dp"最直接 - 如果想“图标内容在自身区域内右对齐”(比如文字图标末尾对齐),才用
android:gravity="end" - 慎用
android:padding:它会缩放 drawable 内容,可能模糊矢量图或拉伸位图 -
android:inset是安全选择,它只收缩 drawable 占用区域,不改变渲染逻辑
为什么有些手机上 gravity 表现不一致?
主要来自 drawable 类型差异和系统渲染路径不同。Bitmap、ColorDrawable、ShapeDrawable 对 gravity 的响应逻辑并不完全统一,尤其在低分辨率屏或旧系统上。
容易被忽略的点:
– <shape></shape> 默认无 intrinsic size,gravity 表现依赖你是否显式设了 android:width/android:height
– <vector></vector> 在 Android 5.0 以下通过 VectorDrawableCompat 渲染,gravity 支持有限,部分值(如 clip_vertical)会被忽略
- 测试时务必覆盖 Android 5.0、8.0、12+ 三个典型版本
- 避免用
fill_horizontal这类复合值,拆成left|right更可控 - 真要跨版本稳定对齐,优先用固定尺寸 + 负边距,而不是依赖 gravity










