android:bottom仅作用于layer-list的子项,控制其内容底部向上收缩,值越大图形越上移;须设在item内而非layer-list根标签,整体下移应靠父容器布局属性或inset drawable。

layer-list 中 bottom 偏移用 android:bottom,但只对子项生效
在 layer-list 里,android:bottom 不是控制整个图层离父容器底部的距离,而是控制该子项(比如一个 shape)自身内容的底部边界向内收缩多少。它本质是「裁剪+定位」:值越大,图形越往上“缩”,看起来像“离底部更远”。
常见错误现象:android:bottom="20dp" 加在最外层 layer-list 标签上——无效,因为 layer-list 自身不支持 android:bottom;必须加在具体子项(如 <item></item>)里。
-
android:bottom只作用于当前<item></item>的 drawable 内容,不影响其他图层 - 若子项是
bitmap,android:bottom会裁掉底部像素;若是shape,则等效于给 shape 的 bottom 边界留空 - 负值允许,但可能导致内容被截断或绘制到不可见区域
想让整个 layer-list 图形整体下移?得靠父容器 padding/margin 或 item 的 gravity
真正控制“图层整体距离父布局底部多远”,靠的是引用这个 drawable 的 View(比如 ImageView)的布局属性,或者用 <item></item> 的 android:gravity 配合尺寸约束。
使用场景:比如你有一个底部悬浮按钮的阴影,需要 shadow 图层比按钮本身再低 4dp 来模拟真实投影高度。
- 推荐做法:在
<item></item>里设android:gravity="bottom",再用android:bottom="4dp"往上收一点,实现“底部对齐后微调” - 避免直接在父 View 上用
android:layout_marginBottom,容易和主题 padding 冲突,尤其在CoordinatorLayout或BottomNavigationView场景下 - 如果父容器是
FrameLayout,且子 View 是match_parent,那android:bottom在<item></item>里的效果最直观
android:bottom 和 android:top/android:left/android:right 行为不一致?
它们行为完全一致,都是对当前 <item></item> 的 drawable 进行内边距式收缩。但视觉上 bottom 更容易误判,因为人眼习惯从顶部读布局,而 bottom 的收缩方向反直觉:值增大 → 图形上移。
参数差异:
-
android:top="10dp":内容顶部向下推 10dp,图形整体下移 -
android:bottom="10dp":内容底部向上收 10dp,图形整体上移 - 两者同时存在时,drawable 实际可用区域 = 原尺寸 − top − bottom(同理 left/right),超出部分被裁剪
性能影响几乎为零,但过度使用负值或超大值可能触发软件渲染(尤其在旧 Android 版本中)。
真要精确控制图层底部位置?用 inset drawable 更可靠
如果你发现 layer-list + android:bottom 总是达不到预期距离,尤其是涉及多图层叠加、缩放或不同 density 屏幕时,inset 是更明确的选择。
inset 是独立 drawable 类型,专为“给内部 drawable 加边距”设计,语义清晰,无歧义:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/my_shape"
android:insetBottom="8dp" />
然后把这个 inset 当作一个图层放进 layer-list 里。相比 android:bottom,它不会改变 gravity 行为,也不依赖父容器测量逻辑。
容易踩的坑:
-
insetBottom的值不会被自动按 density 缩放,务必用 dp 单位(不是 px) - 不能直接在
layer-list的<item></item>标签上混用android:bottom和android:drawable指向一个inset—— 会忽略inset的 inset 值 - Android 4.0+ 全支持,无需兼容降级
复杂点在于:当图层本身有 scale、rotate 或 level-list 逻辑时,inset 的生效时机早于这些变换,所以顺序很重要——先 inset 再变换,别反过来。










