fillcolor 在 vector xml 中不能直接写在 内部以稳定生效,因其仅作为默认填充且易被 android:tint 或自动着色覆盖;应禁用自动着色并统一用 tint 控制颜色。

pathData 里不能直接写 fillColor
很多人在写 vector XML 时,把 fillColor 放在 <path></path> 标签内部,像这样:
<path android:pathData="M10,10 L20,10 L20,20 Z" android:fillColor="#FF0000" />
这看起来合理,但实际无效——fillColor 是 <path></path> 的合法属性,但它只在 android:tint 或着色模式未启用时才生效;一旦父 <vector></vector> 设置了 android:tint,或该 vector 被用作 app:srcCompat 且主题启用了自动着色(比如 AppCompatImageView),fillColor 就会被覆盖或忽略。
-
fillColor不是“强制填充”,而是“默认填充”,它不抵抗着色逻辑 - 如果 vector 在
ImageView中使用app:srcCompat,且没有显式禁用着色,系统会优先走 tint 流程 - Android 5.0+ 默认对
VectorDrawable启用自动着色,除非你主动关掉
想稳定控制颜色,得关掉自动着色或改用 tint
最可靠的方式不是依赖 fillColor,而是让 vector 完全“透明”(即用 #00000000 填充),然后统一用 tint 控制显示色。两种常用路径:
- 在 XML 中:给
<vector></vector>加android:tint="@color/xxx",同时把所有fillColor改成#00000000(或删掉,它默认就是透明) - 在代码中:用
imageView.setColorFilter(...)或AppCompatResources.getColorStateList()动态设色 - 如果必须保留
fillColor行为(比如复用旧资源),就在加载时调用vector.setTintMode(PorterDuff.Mode.SRC_IN)并确保没设tint属性
注意:android:tint 只作用于 <vector></vector> 根标签,对单个 <path></path> 无效;而 fillColor 是每个 <path></path> 自己的属性,但容易被上层覆盖。
多色 vector 怎么办?别硬塞多个 fillColor
一个 vector 文件里有多个 <path></path>,你想各自填不同颜色?可以,但得满足两个前提:
- 必须禁用整个 vector 的
tint(XML 里不写android:tint,代码里不调setColorFilter) - 每个
<path></path>显式写android:fillColor,且值不能是 theme 引用(如?attr/colorPrimary),因为 vector 解析时不支持动态属性绑定 - 如果要适配深色模式,就得准备两套 vector XML(
drawable-night/下放另一份),不能靠 color resource 切换
示例片段:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M12,2 L13.09,8.26 L20,8.26 L14.5,12.45 L16.27,19.26 L12,16.5 L7.73,19.26 L9.5,12.45 L4,8.26 L10.91,8.26 Z" android:fillColor="#FF5722" /> <path android:pathData="M12,12.5 L12,12.5 L12,12.5 Z" android:fillColor="#2196F3" /> </vector>
兼容性陷阱:API 21 以下 fillColor 不生效
如果你还在支持 Android 4.4(API 19)或 5.0(API 21)以下设备,VectorDrawableCompat 对 fillColor 的解析有 bug:某些版本会忽略它,或错误地将 fillColor 当作 stroke 颜色渲染。
- 最低支持 API 21 的项目可放心用
fillColor(但仍受 tint 影响) - 需兼容 API 19 的,建议全部改用
tint+ 单色 vector 方案,避免路径级颜色控制 - gradle 中开启
vectorDrawables.useSupportLibrary = true后,app:srcCompat才能正确解析fillColor,否则可能 fallback 到 PNG
真正难的不是写对颜色值,而是搞清「谁在控制颜色」——是 vector 自己、ImageView 的 tint、Theme 的 colorControlNormal,还是 Context 的 ColorStateList。这些层叠关系一乱,fillColor 就成了幻觉。