Android Drawable XML 资源非常丰富,用于定义各种图形、背景、状态效果和动画,这些 XML 文件通常存放在 res/drawable/ 目录下。
官方文档:https://developer.android.com/guide/topics/resources/drawable-resource
一、基础图形与位图 (Basic Shapes & Bitmaps)
1. <shape> (GradientDrawable)
最常用的标签之一,用于定义几何形状(矩形、椭圆、圆环、线)。常用子标签:
<solid>: 填充颜色。<stroke>: 描边(边框宽度和颜色)。<corners>: 圆角半径。<gradient>: 渐变色(线性、放射、扫描)。<padding>: 内边距。<size>: 固定大小。
这是最复杂的标签之一,属性取决于 android:shape 的类型。
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
<!-- 形状类型: rectangle(矩形-默认), oval(椭圆), line(线), ring(圆环) -->
android:shape="rectangle"
<!-- 仅当 shape="ring" 时有效: -->
android:innerRadius="10dp" <!-- 内环半径 -->
android:innerRadiusRatio="3" <!-- 内环半径比率 (宽度/比率) -->
android:thickness="5dp" <!-- 环的厚度 -->
android:thicknessRatio="9" <!-- 环厚度比率 -->
android:useLevel="false" <!-- 是否作为 LevelListDrawable 使用 (通常设为 false) -->
android:dither="true" <!-- 开启颜色抖动,使低色深屏幕显示更平滑 -->
android:visible="true" <!-- 是否可见 -->
android:tint="#FF0000" <!-- 着色 -->
android:tintMode="src_in"> <!-- 着色模式 -->
<!-- 1. 填充颜色 -->
<solid
android:color="#FFFFFF" />
<!-- 2. 渐变色 (与 solid 互斥) -->
<gradient
android:type="linear" <!-- linear(线性-默认), radial(放射), sweep(扫描) -->
android:angle="90" <!-- 渐变角度,必须是 45 的倍数 (0=左到右, 90=下到上) -->
android:centerX="0.5" <!-- 渐变中心 X 坐标 (0.0 - 1.0) -->
android:centerY="0.5" <!-- 渐变中心 Y 坐标 -->
android:startColor="#FF0000" <!-- 起始颜色 -->
android:centerColor="#00FF00"<!-- 中间颜色 (可选) -->
android:endColor="#0000FF" <!-- 结束颜色 -->
android:gradientRadius="50dp"<!-- 渐变半径 (仅当 type="radial" 时必须) -->
android:useLevel="false" /> <!-- 是否根据 Level 调整渐变 -->
<!-- 3. 描边/边框 -->
<stroke
android:width="2dp" <!-- 边框宽度 -->
android:color="#000000" <!-- 边框颜色 -->
android:dashWidth="5dp" <!-- 虚线段长度 (设为 0 为实线) -->
android:dashGap="2dp" /> <!-- 虚线间隔 -->
<!-- 4. 圆角 (仅 rectangle 有效) -->
<corners
android:radius="5dp" <!-- 统一圆角半径 -->
<!-- 或者单独设置: -->
android:topLeftRadius="5dp"
android:topRightRadius="5dp"
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp" />
<!-- 5. 内边距 (影响使用该 Drawable 的 View 的 content) -->
<padding
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
<!-- 6. 固定大小 (通常用于 ImageView src,作为背景时通常会自动拉伸) -->
<size
android:width="100dp"
android:height="50dp" />
</shape>
2. <bitmap> (BitmapDrawable)
用于包装一个现有的图片资源(PNG/JPG/WebP)。用途:设置图片的平铺模式 (tileMode)、重力 (gravity) 或抗锯齿属性,比直接引用图片更灵活。
对图片资源进行包装,常用于需要平铺或对齐的场景。
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/my_image" <!-- 资源引用 -->
android:antialias="true" <!-- 开启抗锯齿 (图片更平滑) -->
android:dither="true" <!-- 开启抖动 (低色深屏幕优化) -->
android:filter="true" <!-- 开启过滤 (缩放时优化画质) -->
android:mipMap="false" <!-- 是否开启 mipMap 提示 -->
android:autoMirrored="true" <!-- RTL 镜像 -->
<!-- 平铺模式: disabled(默认), clamp(拉伸边缘), repeat(重复), mirror(镜像重复) -->
android:tileMode="repeat" <!-- 同时设置 X 和 Y 轴 -->
android:tileModeX="repeat" <!-- 单独设置 X 轴 -->
android:tileModeY="clamp" <!-- 单独设置 Y 轴 -->
<!-- 对齐方式: 当图片小于容器时,控制图片位置 -->
<!-- 常用: center, top, bottom, left, right, fill, clip_vertical 等 -->
android:gravity="center"
android:alpha="1.0" /> <!-- 透明度 -->
3. <nine-patch> (NinePatchDrawable)
虽然通常使用 .9.png 文件,但也可以通过 XML 定义 .9 图的处理方式(较少用)。
4. <color> (ColorDrawable)
定义一个单色 Drawable。通常直接在 colors.xml 定义颜色,但如果需要一个 Drawable 对象是纯色的,可以用这个标签。
二、状态与交互 (States & Interaction)
5. <selector> (StateListDrawable)
核心标签,根据 View 的状态(按下、选中、禁用、聚焦等)显示不同的 Drawable。子标签:<item> (定义每个状态对应的 drawable 和状态属性,如 android:state_pressed="true")
用于状态选择,属性主要集中在状态标志位上。
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="false" <!-- 所有状态是否使用其最大的固有尺寸 -->
android:dither="true" <!-- 图片抖动处理 -->
android:variablePadding="false" <!-- Padding 是否随状态改变 -->
android:enterFadeDuration="200" <!-- 状态改变时的淡入时间 (ms) -->
android:exitFadeDuration="200" <!-- 状态改变时的淡出时间 (ms) -->
android:autoMirrored="true"> <!-- RTL 布局下是否自动镜像 -->
<!-- item 的匹配顺序是从上到下,找到第一个匹配的就停止,所以默认状态放在最后 -->
<item
android:drawable="@drawable/bg_pressed"
<!-- 常见状态 (true 表示处于该状态,false 表示不处于,不写表示不关心) -->
android:state_pressed="true" <!-- 按下 -->
android:state_focused="true" <!-- 获得焦点 (如 EditText, TV遥控器) -->
android:state_hovered="true" <!-- 鼠标/笔悬停 -->
android:state_selected="true" <!-- 选中 (Tab, List item) -->
android:state_checkable="true" <!-- 可勾选 -->
android:state_checked="true" <!-- 已勾选 (CheckBox) -->
android:state_enabled="true" <!-- 可用 -->
android:state_activated="true" <!-- 激活 (API 11+, 类似 selected) -->
android:state_window_focused="true" <!-- 窗口获得焦点 -->
/>
<!-- 默认状态 -->
<item android:drawable="@drawable/bg_normal" />
</selector>
6. <ripple> (RippleDrawable) (API 21+)
可以实现 Material Design 的水波纹点击效果,可以包含 <item> 来定义背景内容或遮罩 (android:id="@android:id/mask")
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#42000000" <!-- 水波纹的颜色 (必须设置) -->
android:radius="20dp"> <!-- 水波纹扩散的最大半径 (不设置则填满) -->
<!-- 内容层: 也就是未点击时显示的背景 -->
<item
android:id="@android:id/background"
android:drawable="@drawable/my_bg_shape" />
<!-- 遮罩层: 限制水波纹的边界 -->
<!-- 如果不指定 mask,水波纹会扩散出 View 的边界 -->
<item
android:id="@android:id/mask"
android:drawable="@android:color/white" />
</ripple>
7. <animated-selector> (AnimatedStateListDrawable) (API 21+)
<selector> 的升级版,不仅可以在状态之间切换,还可以定义状态切换时的过渡动画。
三、矢量图与动画 (Vectors & Animation)
8. <vector> (VectorDrawable)
定义矢量图形(类似 SVG)。 优点:无损缩放,体积小。子标签:<path> (路径数据), <group> (路径分组,用于变换)
矢量图,属性非常多,分为根节点、Group 和 Path。
<vector xmlns:android="http://schemas.android.com/apk/res/android"
<!-- 画布大小 -->
android:width="24dp"
android:height="24dp"
<!-- 坐标系大小 (pathData 中的数值基于此坐标系) -->
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="#000000" <!-- 整体着色 -->
android:tintMode="src_in"
android:alpha="0.8" <!-- 整体透明度 -->
android:autoMirrored="true">
<!-- Group: 用于对路径进行整体变换 (旋转、缩放、平移) -->
<group
android:name="rotationGroup"
android:pivotX="12" <!-- 旋转/缩放中心 X -->
android:pivotY="12" <!-- 旋转/缩放中心 Y -->
android:rotation="0" <!-- 旋转角度 -->
android:scaleX="1.0" <!-- X 轴缩放 -->
android:scaleY="1.0" <!-- Y 轴缩放 -->
android:translateX="0" <!-- X 轴平移 -->
android:translateY="0"> <!-- Y 轴平移 -->
<!-- Path: 具体的绘制路径 -->
<path
android:name="v_check"
android:pathData="M10,20 L5,5 Z" <!-- SVG 路径数据 -->
android:fillColor="#FF0000" <!-- 填充颜色 -->
android:fillAlpha="1.0" <!-- 填充透明度 -->
android:fillType="nonZero" <!-- 填充规则: nonZero, evenOdd -->
android:strokeColor="#00FF00" <!-- 描边颜色 -->
android:strokeWidth="2" <!-- 描边宽度 -->
android:strokeAlpha="1.0" <!-- 描边透明度 -->
android:strokeLineCap="round" <!-- 线头形状: butt, round, square -->
android:strokeLineJoin="round" <!-- 连接处形状: miter, round, bevel -->
android:strokeMiterLimit="10"
<!-- 路径修剪 (常用于动画,取值 0.0 到 1.0) -->
android:trimPathStart="0.0" <!-- 从路径的哪里开始绘制 (0=开头) -->
android:trimPathEnd="1.0" <!-- 绘制到哪里结束 (1=结尾) -->
android:trimPathOffset="0.0" /> <!-- 路径偏移量 -->
</group>
</vector>
9. <animated-vector> (AnimatedVectorDrawable)
将 <vector> 和属性动画 (ObjectAnimator) 结合,实现矢量图的路径变形、旋转、颜色变化等动画。
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_vector_arrow"> <!-- 引用静态的 vector xml -->
<!-- 将动画作用于 vector 中指定 name 的 group 或 path -->
<target
android:name="rotationGroup" <!-- 对应 vector 中 group 的 name -->
android:animation="@animator/anim_rotate" /> <!-- 引用 animator 资源 -->
<target
android:name="v_check" <!-- 对应 vector 中 path 的 name -->
android:animation="@animator/anim_path_morph" />
</animated-vector>
10. <animation-list> (AnimationDrawable)
帧动画,像放电影一样通过 <item> 顺序播放一系列图片。
逐帧动画(Frame Animation)。
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" <!-- true: 只播放一次; false: 循环播放 -->
android:variablePadding="false" <!-- 是否随当前帧改变 Padding -->
android:visible="true">
<!-- 每一帧 -->
<item
android:drawable="@drawable/frame_1" <!-- 当前帧图片 -->
android:duration="100" /> <!-- 当前帧显示时长 (毫秒) -->
<item
android:drawable="@drawable/frame_2"
android:duration="100" />
</animation-list>
四、图层与组合 (Layers & Composition)
11. <layer-list>** (LayerDrawable)
将多个 Drawable 像图层一样叠加在一起(类似 Photoshop 的图层)。用途:组合复杂的背景(例如:底部阴影 + 白色背景 + 顶部边框)。
图层叠加,类似于 FrameLayout。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque" <!-- 设置不透明度: opaque, translucent, transparent -->
android:autoMirrored="true"
android:paddingMode="nest"> <!-- 处理内边距的方式: nest(嵌套-默认), stack(堆叠) -->
<item
android:id="@+id/background_layer" <!-- 设置 ID,可在代码中获取 -->
android:drawable="@drawable/bg" <!-- 引用的 Drawable -->
<!-- 定位与偏移 -->
android:gravity="center" <!-- 对齐方式 -->
android:left="10dp" <!-- 左偏移 -->
android:right="10dp" <!-- 右偏移 -->
android:top="10dp" <!-- 上偏移 -->
android:bottom="10dp" <!-- 下偏移 -->
android:start="10dp" <!-- RTL 支持 -->
android:end="10dp" <!-- RTL 支持 -->
<!-- 显式尺寸 (API 23+) -->
android:width="50dp"
android:height="50dp">
<!-- 也可以在 item 内部直接定义 shape 等 -->
<!-- <shape ... /> -->
</item>
</layer-list>
12. <level-list> (LevelListDrawable)
根据设置的 Level 值 (setLevel()) 切换显示不同的 Drawable 用途:音量图标(静音、低、中、高)、电池电量图标。
管理多个 Drawable,根据 setLevel() 的值显示其中一个。
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 比如电池电量: level 0-10 显示红色电池 -->
<item
android:drawable="@drawable/battery_low"
android:minLevel="0"
android:maxLevel="10" />
<!-- level 11-100 显示绿色电池 -->
<item
android:drawable="@drawable/battery_full"
android:minLevel="11"
android:maxLevel="100" />
</level-list>
13. <transition> (TransitionDrawable)
在两个 Drawable 之间实现淡入淡出效果(通常用于 startTransition())。
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 只支持两个 item -->
<!-- 初始显示的 Drawable -->
<item
android:id="@+id/off"
android:drawable="@drawable/mode_off" />
<!-- 过渡后显示的 Drawable -->
<item
android:id="@+id/on"
android:drawable="@drawable/mode_on" />
</transition>
五、包装与修饰 (Wrappers & Modifiers)
这些标签通常用来包裹另一个 Drawable,对其进行特定的变换。
14. <inset> (InsetDrawable)
将内部的 Drawable 向内缩进。用途:让背景图片小于 View 的实际边界(例如给 ListView 的分割线加 margin)。
用于处理背景图的内边距,常用于让分割线或背景比 View 实际大小稍小一点。
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/bg_shape" <!-- 内部 Drawable -->
android:visible="true"
<!-- 统一缩进 -->
android:inset="10dp"
<!-- 单独方向缩进 -->
android:insetLeft="10dp"
android:insetRight="10dp"
android:insetTop="0dp"
android:insetBottom="0dp"
<!-- API 21+: 按照百分比缩进 (0.0 - 1.0) -->
android:fraction="0.1" />
15. <clip> (ClipDrawable)
根据 Level 值裁剪内部的 Drawable。用途:实现进度条效果(从左向右慢慢显示图片)。
根据 Level 值 (0-10000) 裁剪图片,常用于制作自定义进度条。
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/img_progress"
<!-- 裁剪方向: horizontal(水平), vertical(垂直) -->
android:clipOrientation="horizontal"
<!-- 裁剪重心: 决定从哪边开始显示 -->
<!-- left: 进度从左向右长 (常用) -->
<!-- bottom: 进度从底向上长 -->
<!-- center: 从中间向两边扩散 -->
android:gravity="left" />
16. <scale> (ScaleDrawable)
根据 Level 值缩放内部的 Drawable。
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/img_logo"
<!-- 缩放重心 -->
android:scaleGravity="center"
<!-- 缩放比例: 这里的含义是“缩减”的比例 -->
<!-- 100%: 意味着 level 0 时图片完全消失 (缩减了100%) -->
<!-- 10%: 意味着 level 0 时图片缩小 10% -->
android:scaleHeight="100%"
android:scaleWidth="100%"
<!-- 初始 level (API 19+) -->
android:level="1" />
17. <rotate> (RotateDrawable)
根据 Level 值旋转内部的 Drawable。 用途:加载中的转圈图标(Loading Spinner)。
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_spinner"
android:visible="true"
<!-- 旋转起始角度 -->
android:fromDegrees="0"
<!-- 旋转结束角度 -->
android:toDegrees="360"
<!-- 旋转中心点 (默认是 50%, 即中心) -->
android:pivotX="50%"
android:pivotY="50%" />
六、自适应图标 (Adaptive Icons - Android 8.0+)
18. <adaptive-icon> (AdaptiveIconDrawable)
定义 Android 8.0 及以上版本的自适应应用图标。子标签:<background>, <foreground>.
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 背景层 (可以是颜色或图片) -->
<background android:drawable="@color/ic_background" />
<!-- 前景层 (图标主体,必须是透明背景) -->
<foreground android:drawable="@drawable/ic_foreground" />
</adaptive-icon>
七、总结
虽然标签非常多,但最核心的 “三剑客” 是:
<shape>: 搞定 80% 的 UI 背景。
<selector>: 搞定所有的交互状态(按压、选中)。
<vector>: 搞定所有的图标(Icon)。
其他标签通常是在遇到特定需求(如复杂的叠加、特殊的裁剪动画、水波纹)时才会用到,再掌握以下 2 个,涵盖了 90% 的 UI 开发需求:
<layer-list>: 叠加图标或给背景加红点/阴影。
<ripple>: 给按钮添加水波纹反馈。
| 标签 | 用途 |
|---|---|
<shape> | 背景、圆角 |
<selector> | 状态切换 |
<layer-list> | 多层叠加 |
<ripple> | 水波纹 |
<vector> | 矢量图 |
<animation-list> | 帧动画 |
<clip> | 进度条 |
<scale> | 缩放 |
634

被折叠的 条评论
为什么被折叠?



