【Android UI】Android Drawable XML 标签解析

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 的类型。

xml 复制代码
<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) 或抗锯齿属性,比直接引用图片更灵活。

对图片资源进行包装,常用于需要平铺或对齐的场景。

xml 复制代码
<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")

用于状态选择,属性主要集中在状态标志位上。

xml 复制代码
<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")

xml 复制代码
<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。

xml 复制代码
<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) 结合,实现矢量图的路径变形、旋转、颜色变化等动画。

xml 复制代码
<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)。

xml 复制代码
<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。

xml 复制代码
<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() 的值显示其中一个。

xml 复制代码
<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())。

xml 复制代码
<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 实际大小稍小一点。

xml 复制代码
<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) 裁剪图片,常用于制作自定义进度条。

xml 复制代码
<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。

xml 复制代码
<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)。

xml 复制代码
<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>.

xml 复制代码
<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> 缩放
相关推荐
jinxinyuuuus6 小时前
Wallpaper Generator:前端性能优化、UI状态管理与实时渲染的用户体验
前端·ui·性能优化
都是蠢货6 小时前
mysql中null是什么意思?
android·数据库·mysql
Just_Paranoid6 小时前
【Android UI】Android 创建渐变背景 Drawable
android·ui·drawable·shape·gradient
千里马学框架6 小时前
AI豆包手机权限文章补充:Mainfest中某个权限的protectionLevel具体是如何被系统定义的?
android·智能手机·framework·权限·protectionlevel
鹏多多6 小时前
flutter使用package_info_plus库获取应用信息的教程
android·前端·flutter
走在路上的菜鸟7 小时前
Android学Dart学习笔记第十五节 类
android·笔记·学习·flutter
2501_916008897 小时前
IOScer 证书到底是什么和怎么使用的完整说明
android·ios·小程序·https·uni-app·iphone·webview
Aevget7 小时前
DevExpress WPF中文教程:Data Grid - 如何绑定到有限制的自定义服务(一)?
ui·.net·wpf·devexpress·ui开发·wpf界面控件