m、l、z 操作同一隐式“当前点”:m 重置起点,l 从此画线,z 闭合回 m 的初始位置;大小写敏感,z 无参数,坐标基于 viewport 归一化,空格/逗号格式错误会导致静默解析失败。

pathData 里的 M L Z 到底在动哪个点
它们操作的是同一个隐式「当前点」,不是各自独立的起点。M 移动画笔位置,L 从该点画线到新坐标,Z 自动连回最初 M 的位置——不是上一个 L 的终点,也不是任意点,就是 M 那一下定下的原点。
常见错误现象:Path 渲染出错、图形偏移、闭合失败,往往是因为误以为 Z 是“闭合上一段”,结果 M 后又跟了多个 L 却只 Z 一次,导致只有第一段被闭合。
- M 后面必须跟两个数字(x y),它重置「当前点」,后续所有相对指令(如
l、c)都以此为基准 - L 是绝对坐标;小写
l才是相对移动,别混用大小写——Android 不区分大小写的解析器不存在,L和l行为完全不同 - Z 不接受参数,写成
Z100,100会直接解析失败,报错android.view.InflateException: Binary XML file line #X: invalid pathData
vector drawable 中 pathData 的坐标单位和缩放关系
所有数值默认是「原始像素单位」,但实际显示尺寸由 android:viewportWidth 和 android:viewportHeight 共同决定。它不是屏幕像素,也不是 dp,而是一套归一化坐标系——类似 SVG 的 viewBox。
使用场景:想让图标在不同密度屏上保持清晰,就得靠 viewport + pathData 配合缩放,而不是硬写 48dp 或 24px。
- 假设
viewportWidth="24",pathData 里写M0,0 L24,24,就刚好撑满整个视口 - 如果 viewport 是
100,但 pathData 还沿用M0,0 L24,24,图形就会缩成左上角一小块,其余全是空白 - 不要在 pathData 里手动除以密度比(如 /2 或 /3),VectorDrawable 本身不感知 density,缩放由系统根据
android:width/android:height和 viewport 比例自动完成
为什么 L 连续写多次没反应,或线条突然断开
因为 pathData 解析器对空格和逗号敏感,且会跳过非法字符,但不会报错——它静默丢弃异常片段,导致后续指令偏移,看起来像“漏画”或“接不上”。
典型错误现象:明明写了 M10,10 L20,20 L30,30,结果只显示第一条线;或者最后一条 L 完全不出现。
- 逗号前后不能有换行或制表符,
L20,20\nL30,30在某些 Android 版本(尤其是 5.0–6.0)会被截断解析 - 数字之间至少一个空格或逗号,但不能混用混乱,比如
L20,20 30,30是非法的——这会被当成L20,20加一个孤立的30,30,后者无指令前缀,直接忽略 - 负数必须带负号,
L20,-20正确,L20,−20(用全角减号)会导致解析中断,后面全失效
pathData 性能影响:太长的指令链真会影响渲染吗
会影响,但不是 CPU 解析耗时,而是 GPU 渲染路径复杂度。Android 会把 vector 转成 Path 对象再交给 Skia,顶点数越多、曲线越密,光栅化压力越大,尤其在列表中高频复用时可能掉帧。
使用场景:自定义 loading 动画、Tab 图标切换、RecyclerView item 中的 icon。
- 单个
pathData字符串超过 500 字符不是问题,但若含大量微小L模拟曲线(比如用 50 段直线画圆),不如改用C或A指令 - 避免重复 M→L→L→L→Z 堆叠多个小形状,合并成一个 path 更高效;系统对单个
pathData的优化远好于多个<path></path>标签 - Android 7.0+ 支持
android:pathData动态设置,但每次 set 都触发重解析,频繁调用(如动画中)建议提前缓存Path对象
真正容易被忽略的是 viewport 和 pathData 的比例直觉——人眼习惯看绝对像素,但 vector 里写 10 和写 1000 只要同比例缩放,效果一样;可一旦 viewport 设错,再怎么调 pathData 都白搭。










