> 技术文档 > Android Drawable 目录下的 XML 图形文件详解_android drawable xml

Android Drawable 目录下的 XML 图形文件详解_android drawable xml


文章目录

    • 一、基本 XML Drawable 类型
      • 1. 矢量图形 (VectorDrawable)
      • 2. 形状图形 (ShapeDrawable)
      • 3. 图层列表 (LayerDrawable)
      • 4. 状态列表 (StateListDrawable)
      • 5. 动画矢量图 (AnimatedVectorDrawable)
    • 二、高级技巧与应用
      • 1. 动态修改 Drawable 属性
      • 2. 主题属性引用
      • 3. 带缩放的矢量图
      • 4. 复杂路径组合
    • 三、最佳实践
  • Android 九宫格图片(.9.png)详解
    • 一、基本概念
      • 1. 什么是九宫格图片
      • 2. 文件特征
    • 二、创建九宫格图片
      • 1. 使用 Android Studio 创建
      • 2. 手动创建
    • 三、九宫格图片结构详解
      • 1. 四条黑边的含义
      • 2. 详细说明
    • 四、实际示例
      • 1. 示例图片分析
      • 2. XML 中使用
    • 五、制作技巧
      • 1. 设计原则
      • 2. 常见错误
    • 六、高级应用
      • 1. 动态修改九宫格图片
      • 2. 代码创建 NinePatch
    • 七、常见问题解决
      • 1. 图片边缘出现黑线
      • 2. 图片拉伸不均匀
      • 3. 内容显示不全
      • 4. Android Studio 提示 \"9-patch image malformed\"
    • 八、最佳实践
    • 九、与传统 PNG 对比

在 Android 开发中,res/drawable 目录下的 XML 文件是一种强大的图形资源定义方式,它们比位图资源更灵活、更易于维护。下面我将详细解析各种类型的 Drawable XML 文件及其使用方法。

一、基本 XML Drawable 类型

1. 矢量图形 (VectorDrawable)

文件位置res/drawable/res/drawable-anydpi/

<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:width=\"24dp\" android:height=\"24dp\" android:viewportWidth=\"24.0\" android:viewportHeight=\"24.0\"> <path android:fillColor=\"#FF000000\" android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z\"/></vector>

关键属性

  • width/height:矢量图的固有尺寸
  • viewportWidth/viewportHeight:画布的逻辑尺寸
  • pathData:定义形状的路径数据(SVG 格式)
  • fillColor:填充颜色
  • strokeColor:描边颜色
  • strokeWidth:描边宽度

优点

  • 任意缩放不失真
  • 文件体积小
  • 可通过代码动态修改属性

2. 形状图形 (ShapeDrawable)

文件位置res/drawable/

<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\"> <corners android:radius=\"8dp\" /> <gradient android:angle=\"45\" android:startColor=\"#FF6200EE\" android:endColor=\"#FF03DAC5\" android:type=\"linear\" /> <stroke android:width=\"2dp\" android:color=\"#FFFFFF\" android:dashWidth=\"4dp\" android:dashGap=\"2dp\" /> <size android:width=\"200dp\" android:height=\"100dp\" /></shape>

形状类型

  • rectangle(默认):矩形
  • oval:椭圆
  • line:水平线
  • ring:环形

子元素详解

  • :圆角
    • radius:统一圆角半径
    • topLeftRadius等:各角单独设置
  • :渐变
    • type:linear(线性)/radial(径向)/sweep(扫描)
    • centerX/Y:渐变中心点(0-1)
    • gradientRadius:径向渐变半径
  • :描边
    • dashWidth:虚线段的长度
    • dashGap:虚线间隔
  • :纯色填充
  • :内边距
  • :固有尺寸

3. 图层列表 (LayerDrawable)

<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">  <item android:top=\"4dp\" android:left=\"4dp\"> <shape android:shape=\"rectangle\"> <solid android:color=\"#33000000\" /> <corners android:radius=\"8dp\" /> </shape> </item>  <item> <shape android:shape=\"rectangle\"> <solid android:color=\"#FF6200EE\" /> <corners android:radius=\"8dp\" /> </shape> </item></layer-list>

特点

  • 按顺序堆叠多个 Drawable
  • 每个 可以设置偏移量(left/right/top/bottom)
  • 常用于创建复杂组合效果(如带阴影的按钮)

4. 状态列表 (StateListDrawable)

<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">  <item android:state_pressed=\"true\"> <shape android:shape=\"rectangle\"> <solid android:color=\"#FF3700B3\" /> <corners android:radius=\"8dp\" /> </shape> </item>  <item> <shape android:shape=\"rectangle\"> <solid android:color=\"#FF6200EE\" /> <corners android:radius=\"8dp\" /> </shape> </item></selector>

常用状态属性

  • state_pressed:按下状态
  • state_focused:获得焦点
  • state_selected:选中状态
  • state_enabled:启用状态(false 表示禁用)
  • state_checked:勾选状态(用于 CheckBox 等)
  • state_activated:激活状态

重要规则

  • 状态匹配是第一个符合条件的项
  • 最后一个 item 应作为默认状态(不指定任何状态)

5. 动画矢量图 (AnimatedVectorDrawable)

组成

  1. 矢量图 (VectorDrawable)
  2. 动画定义 (ObjectAnimator)
  3. 动画矢量图 (AnimatedVectorDrawable)

示例

<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:drawable=\"@drawable/ic_heart\"> <target android:name=\"heart\" android:animation=\"@animator/heart_beat\" /></animated-vector>
<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:width=\"24dp\" android:height=\"24dp\" android:viewportWidth=\"24.0\" android:viewportHeight=\"24.0\"> <path android:name=\"heart\" android:pathData=\"M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z\" android:fillColor=\"#FF0000\" /></vector>
<set xmlns:android=\"http://schemas.android.com/apk/res/android\"> <objectAnimator android:propertyName=\"scaleX\" android:duration=\"300\" android:valueFrom=\"1\" android:valueTo=\"1.2\" android:valueType=\"floatType\" android:repeatCount=\"1\" android:repeatMode=\"reverse\" /> <objectAnimator android:propertyName=\"scaleY\" android:duration=\"300\" android:valueFrom=\"1\" android:valueTo=\"1.2\" android:valueType=\"floatType\" android:repeatCount=\"1\" android:repeatMode=\"reverse\" /></set>

使用方法

ImageButton heartButton = findViewById(R.id.heart_button);AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create( this, R.drawable.avd_heart);heartButton.setImageDrawable(avd);avd.start();

二、高级技巧与应用

1. 动态修改 Drawable 属性

// 修改矢量图颜色VectorDrawableCompat vector = VectorDrawableCompat.create( getResources(), R.drawable.ic_vector, getTheme());vector.setTint(ContextCompat.getColor(this, R.color.new_color));// 修改形状圆角GradientDrawable shape = (GradientDrawable) view.getBackground();shape.setCornerRadii(new float[]{ 0, 0, // 左上 20, 20, // 右上 40, 40, // 右下 0, 0  // 左下});

2. 主题属性引用

<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"> <solid android:color=\"?attr/colorPrimary\" /> <stroke android:width=\"1dp\" android:color=\"?attr/colorPrimaryDark\" /></shape>

3. 带缩放的矢量图

<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:width=\"24dp\" android:height=\"24dp\" android:viewportWidth=\"24.0\" android:viewportHeight=\"24.0\"> <group android:name=\"rotationGroup\" android:pivotX=\"12\" android:pivotY=\"12\" android:rotation=\"0\"> <path android:name=\"v\" android:fillColor=\"#000000\" android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z\" /> </group></vector>

4. 复杂路径组合

<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:width=\"24dp\" android:height=\"24dp\" android:viewportWidth=\"24.0\" android:viewportHeight=\"24.0\"> <path android:name=\"circle\" android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2z\" android:fillColor=\"#4CAF50\" /> <path android:name=\"check\" android:pathData=\"M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z\" android:fillColor=\"#FFFFFF\" /></vector>

三、最佳实践

  1. 命名规范

    • 按钮状态:btn_[状态]_[颜色](如 btn_pressed_primary
    • 图标:ic_[名称](如 ic_search
    • 背景:bg_[描述](如 bg_rounded_corner
  2. 性能优化

    • 优先使用矢量图(简单图标)
    • 复杂图形使用 WebP 格式位图
    • 避免在 StateListDrawable 中使用过多层级
  3. 适配技巧

    • 为不同主题提供替代 Drawable(drawable-night/
    • 为不同 API 级别提供兼容版本(drawable-v21/
  4. 工具推荐

    • Android Studio 的 Vector Asset Studio
    • SVG 转 VectorDrawable 在线工具
    • Shape Shifter(高级矢量动画工具)

通过合理使用这些 XML Drawable 资源,你可以创建出既美观又高效的界面元素,同时保持应用的轻量化和可维护性。


Android 九宫格图片(.9.png)详解

九宫格图片(NinePatch Drawable,文件扩展名为 .9.png)是 Android 平台上一种特殊的 PNG 图片格式,它能够智能地拉伸图片而不会使边角变形。

一、基本概念

1. 什么是九宫格图片

九宫格图片将一张图片划分为 9 个部分:

  • 4个角(不拉伸)
  • 4条边(单向拉伸)
  • 1个中心区域(双向拉伸)

2. 文件特征

  • 文件扩展名必须是 .9.png
  • 图片四周有 1 像素的黑边(定义拉伸区域和内容区域)
  • 实际显示时黑边不会显示

二、创建九宫格图片

1. 使用 Android Studio 创建

步骤

  1. 右键点击 res/drawable 目录
  2. 选择 NewImage Asset
  3. Asset Type 中选择 Nine-Patch
  4. 选择源图片并调整黑边

2. 手动创建

  1. 准备普通 PNG 图片
  2. 使用图片编辑工具(如 Photoshop)添加 1 像素的黑边
  3. 按照规则标记拉伸区域和内容区域
  4. 保存为 .9.png 格式

三、九宫格图片结构详解

1. 四条黑边的含义

+---------------------+| 上边:水平拉伸区域 || 左边:垂直拉伸区域 || 右边:垂直内容区域 || 下边:水平内容区域 |+---------------------+

2. 详细说明

边缘 作用 标记规则 上边 定义水平拉伸区域 黑色像素表示可拉伸部分,透明表示不拉伸 左边 定义垂直拉伸区域 黑色像素表示可拉伸部分,透明表示不拉伸 右边 定义垂直内容区域(内边距) 黑色像素表示内容边界 下边 定义水平内容区域(内边距) 黑色像素表示内容边界

四、实际示例

1. 示例图片分析

+-------------------------+| 1px 黑边标记区域 || || +---------------+ || | 角区域(不拉伸) | || | 边区域(拉伸) | || | 中心区域(拉伸) | || +---------------+ || |+-------------------------+

2. XML 中使用

<Button android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:background=\"@drawable/button_background\" />

其中 button_background.9.png 是九宫格图片。

五、制作技巧

1. 设计原则

  • 四个角区域应包含不希望变形的内容(如圆角、装饰元素)
  • 边区域应使用可重复的简单图案
  • 中心区域可以是纯色或简单纹理

2. 常见错误

  • 忘记添加 1 像素的黑边
  • 黑边标记不连续
  • 拉伸区域标记过大导致图片变形明显
  • 内容区域标记不正确导致文字错位

六、高级应用

1. 动态修改九宫格图片

// 获取九宫格图片NinePatchDrawable npd = (NinePatchDrawable) getResources() .getDrawable(R.drawable.button_background);// 修改颜色滤镜npd.setColorFilter(new PorterDuffColorFilter( Color.RED, PorterDuff.Mode.SRC_IN));// 应用到视图button.setBackground(npd);

2. 代码创建 NinePatch

// 加载位图Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.button_background);// 获取 NinePatch 块数据byte[] chunk = bitmap.getNinePatchChunk();// 创建 NinePatchDrawableNinePatchDrawable npd = new NinePatchDrawable( getResources(), bitmap, chunk, new Rect(), null);

七、常见问题解决

1. 图片边缘出现黑线

  • 原因:黑边标记被错误地包含在显示区域
  • 解决:确保只在最外 1 像素标记

2. 图片拉伸不均匀

  • 原因:拉伸区域标记不正确
  • 解决:调整黑边标记,确保可拉伸区域合理

3. 内容显示不全

  • 原因:内容区域(右/下边)标记不正确
  • 解决:调整右/下边黑边标记

4. Android Studio 提示 “9-patch image malformed”

  • 原因:九宫格图片格式错误
  • 解决:
    1. 检查是否有 1 像素的黑边
    2. 检查黑边是否连续
    3. 使用 Android Studio 的绘图工具修复

八、最佳实践

  1. 命名规范:使用 _9 后缀,如 btn_normal_9.png
  2. 最小尺寸:确保图片足够大以适应各种拉伸情况
  3. 测试验证:在不同分辨率和尺寸的设备上测试显示效果
  4. 备用方案:为不同屏幕密度提供多个版本的九宫格图片
  5. 替代方案:对于简单形状,考虑使用 VectorDrawable 或 ShapeDrawable

九、与传统 PNG 对比

特性 九宫格图片 普通 PNG 拉伸方式 智能拉伸 整体拉伸 文件大小 稍大 较小 边角保护 保持原样 会变形 适用场景 按钮/背景 图标/图片 制作复杂度 较高 低

九宫格图片是 Android 开发中处理可拉伸背景的强大工具,合理使用可以显著提升应用的界面适配性和视觉效果。