Vector Drawable 的 pathData 必须全小写命令、空格分隔坐标、避免混用符号;viewportWidth/Height 必须设为正整数以定义逻辑画布;API 21以下需启用兼容模式并使用 app:srcCompat;tint 会覆盖 fillColor,多色图标应禁用 tint。

Vector Drawable 的 pathData 怎么写才不会报错
Android 的 VectorDrawable 不是 SVG,pathData 语法虽类似但限制多。最常见报错是 android.view.InflateException: Binary XML file line #X: invalid pathData,基本都出在坐标格式或命令大小写上。
实操建议:
-
pathData中所有命令必须小写(m,l,c,z),大写会直接崩溃 - 坐标之间用空格或逗号分隔,但不能混用;推荐统一用空格,避免解析歧义
- 不支持相对坐标缩写(如
h10、v-5),必须写全h 10或v -5 - 路径末尾加
z很安全,但不是必须;未闭合路径在某些 Android 版本上可能渲染异常(尤其 API 21–23)
示例(合法):pathData="M 0 0 L 100 0 L 100 100 Z";错误写法:pathData="M0,0L100,0L100,100z"(缺空格、逗号混用、z 小写但前面没空格)
为什么 android:viewportWidth 和 android:viewportHeight 必须设
这两个属性定义了矢量图的逻辑画布尺寸,不是最终显示大小。不设或设为 0 会导致 RuntimeException: viewportWidth/Height must be > 0,且所有 pathData 坐标都会失效——因为系统无法把路径映射到任何空间。
实操建议:
- 设为整数,常见值是
24、48、100,和设计稿的 artboard 尺寸对齐即可 -
viewportWidth和viewportHeight不影响最终缩放,只影响路径坐标的解释比例;比如M 12 12在viewportWidth="24"下就是中心点 - 不要试图用它们“适配屏幕”,那是
android:width/android:height和布局的事
错误现象:图标显示为空白,Logcat 出现 Invalid viewport size —— 八成是这两个值被删了或填了 0。
API 21 以下使用 VectorDrawable 需要哪些兼容处理
原生 VectorDrawable 只支持 API 21+;低于此版本必须靠 AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) + app:srcCompat,否则直接 crash 或静默失败。
实操建议:
- 在
Application或ActivityonCreate()中调用AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)(仅需一次) - XML 中不能用
android:src,必须用app:srcCompat="@drawable/ic_heart"(注意命名空间) - Gradle 插件 3.0+ 默认开启
vectorDrawables.useSupportLibrary = true,但若手动关过,需确认已开启 - 动态加载时别用
Context.getDrawable(),改用AppCompatResources.getDrawable(context, R.drawable.xxx)
典型错误:在 API 19 设备上图标不显示,也没报错——大概率是用了 android:src 或忘了开兼容开关。
android:tint 和 android:fillColor 混用时谁生效
android:tint 是 View 级着色,作用于整个 Drawable;android:fillColor 是 内联属性,只对该路径生效。两者共存时,tint 会覆盖 fillColor,除非 fillColor 设为透明或使用 tintMode 控制混合方式。
实操建议:
- 单色图标优先用
tint,方便主题切换;多色图标必须用fillColor分别设色,且禁用tint - 如果用了
tint还想保留部分路径原色,把那部分路径的fillColor设为#00000000(全透明),再配合tintMode="src_atop" -
tint对strokeColor无效,描边颜色必须用android:strokeColor单独控制
容易忽略的一点:在 StateListDrawable(如 selector)里嵌套 VectorDrawable 时,每个子项的 tint 是独立生效的,别指望父容器统一控制。










