
还在为一张图标准备mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi五套 PNG 吗矢量图VectorDrawable的思路完全不同它不存像素点阵而是存画法——“从这里画一条线到那里再画条曲线收尾”。既然记录的是数学描述那放大到任意尺寸都清晰锐利而且一份 XML 走天下。这就像告诉你画个边长 24 的正方形比给你一张固定分辨率的正方形照片灵活得多。本文讲清矢量图的原理、pathData路径语法、XML 元素全貌、与 SVG 的差异以及兼容性要点。一、矢量图是什么VectorDrawable 是 Android 用 XML 描述二维矢量图形的格式核心优势体积小通常一份 XML 即可不用为每种密度备份。分辨率无关任意缩放不失真。可变换、可动画支持旋转、缩放、属性动画与主题着色。视口viewport与固有尺寸理解矢量图的关键是两套尺寸视口viewportWidth/viewportHeight逻辑坐标系。你画图时所有坐标都基于它比如viewportWidth24表示画布逻辑宽度是 24 个单位。固有尺寸width/height推荐用dp默认显示多大。渲染时系统按缩放系数 目标尺寸 / 视口尺寸进行缩放。所以你用 24×24 的视口画的图标显示成 48dp 也一样清晰。图形结构树矢量图由三类节点组成group分组变换、path实际路径、clip-path裁剪形状。二、XML 元素与属性全览vector根元素vectorxmlns:androidhttp://schemas.android.com/apk/res/androidandroid:width24dp!--固有宽推荐dp--android:height24dp!-- 固有高 --android:viewportWidth24!-- 逻辑坐标宽 --android:viewportHeight24!-- 逻辑坐标高 --可选属性android:tint整体着色、android:tintMode、android:autoMirroredRTL 自动镜像、android:alpha整体不透明度。group分组属性均可动画android:name、android:rotation、android:pivotX/pivotY旋转/缩放中心基于视口坐标、android:scaleX/scaleY、android:translateX/translateY。path路径核心pathandroid:nameringandroid:pathDataM24,6 C34.49,6 43,14.51 43,25 ...android:fillColor#000android:strokeColorandroid:color/holo_blue_lightandroid:strokeWidth4android:strokeLineCaproundandroid:trimPathStart0android:trimPathEnd0.75/属性含义pathData必需路径命令见下节fillColor/fillAlpha填充色/透明度strokeColor/strokeWidth/strokeAlpha描边色/宽度/透明度strokeLineCap端点butt/round/squarestrokeLineJoin拐角miter/round/beveltrimPathStart/End/Offset截取路径的一段描边进度动画常用fillTypenonZero/evenOdd填充规则clip-path裁剪路径只作为裁剪形状本身不可见影响同级及后续绘制内容的可见区域。三、pathData 命令详解pathData借鉴了 SVG 路径语法。每个命令有**大写绝对坐标和小写相对坐标**两种命令含义示例作用M/m移动到M x,y抬笔移到新起点不画线L/l直线到L x,y从当前点画直线到目标H/h水平线H x水平画到指定 xV/v垂直线V y垂直画到指定 yC/c三次贝塞尔C x1,y1 x2,y2 x,y两个控制点 终点S/s三次贝塞尔简写S x2,y2 x,y复用前一控制点的镜像Q/q二次贝塞尔Q x1,y1 x,y一个控制点 终点T/t二次贝塞尔简写T x,y复用前一控制点镜像Z/z闭合路径Z连回子路径起点例如三角形M4,20 L20,20 L12,4 Z移到左下→画到右下→画到顶点→闭合。注意VectorDrawable 不支持SVG 的椭圆弧命令A/a导入时会被转成贝塞尔曲线、虚线描边stroke-dasharray以及circle/rect/polygon等形状元素需转成 path。四、颜色、着色与主题化基础色path的fillColor/strokeColor定义本身颜色。整体着色vector的android:tint或视图层级的ImageView的android:tint/app:tint会对整张图做色彩过滤结果受tintMode影响。主题化引用?attr/colorPrimary适配日夜间/品牌主题复杂场景可用aapt命名空间包装主题属性AGP 新版默认支持。五、完整示例!-- 分组旋转 裁剪 --vectorxmlns:androidhttp://schemas.android.com/apk/res/androidandroid:width100dpandroid:height100dpandroid:viewportWidth100android:viewportHeight100groupandroid:namegandroid:pivotX50android:pivotY50android:rotation45clip-pathandroid:pathDataM10,10 L90,10 L90,90 L10,90 Z/pathandroid:fillColor#4CAF50android:pathDataM20,20 H80 V80 H20 Z//group/vector六、矢量图 vs 位图PNG/WebP维度VectorDrawable位图PNG/WebP体积小一份资源需多密度副本清晰度任意缩放无损放大模糊渲染性能简单图形高效复杂图形/照片更稳动画与主题易做属性动画、着色需额外技巧兼容性旧机需 AppCompat 支持全版本通用适用图标、简单图形照片、复杂插画经验法则图标和简单图形用矢量图照片和复杂插画用 WebP 位图。路径节点特别多的复杂矢量反而会拖慢渲染。七、兼容性要点原生 VectorDrawable 需API 21。低版本通过AppCompat支持库兼容。在低版本上布局里要用app:srcCompat而非android:src引用矢量图并在 Gradle 启用android{defaultConfig{vectorDrawables.useSupportLibrarytrue}}用 Android Studio 的Vector Asset工具导入 SVG注意查看导入报告弧线会被自动替换为贝塞尔曲线。