在Android开发中,使用矢量图(Vector Drawable)替代位图已经是主流做法。矢量图通过XML描述图形,其中path节点负责定义具体的形状轮廓,而fillColor属性则决定这个轮廓内部使用什么颜色进行填充。正确理解并运用fillColor,可以避免图标不显示、颜色不对或者主题适配失效等问题。

一、fillColor的基本用法
fillColor是<path>标签的一个属性,用来设置路径的填充颜色。最基础的写法是直接使用十六进制颜色值,格式与Android中其他颜色定义一致,支持带透明度的ARGB或不含透明度的RGB。例如下面这段XML定义了一个红色的圆形路径:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF0000"
android:pathData="M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2Z"/>
</vector>
上述代码中,pathData描述了圆形的轮廓,fillColor="#FF0000"表示用不透明的红色填满这个圆形。这种写法简单直观,适合颜色固定不变的图标。但如果项目需要支持多主题或者暗黑模式,硬编码颜色就会带来维护成本。
除了直接写色值,fillColor也支持引用颜色资源。我们可以在res/values/colors.xml里定义颜色,然后在vector中通过@color/名称来引用。这样做可以把颜色集中管理,在换肤或主题切换时只需修改资源文件。注意引用资源时不需要写十六进制前缀,系统会在编译期绑定对应的值。
二、使用资源引用与主题属性
当图标颜色需要跟随应用主题变化时,使用@color引用已经不够灵活,此时可以使用主题属性引用,例如?attr/colorPrimary。这种方式让vector在运行时根据当前主题自动取色,特别适合工具栏图标、背景装饰图形等场景。
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorPrimary"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/>
</vector>
上面的例子把房子形状的path填充色绑定到主题的colorPrimary上。在暗黑主题下,只要colorPrimary被重新定义,图标颜色就会自动变化,不需要为不同主题准备多份矢量图。不过要注意,使用?attr/引用的vector在非兼容环境下可能失效,需确保通过AppCompat加载。
另外,也可以将fillColor指向一个selector颜色资源,实现按压、选中等状态切换。比如定义一个res/color/icon_state.xml,里面用<selector>包裹不同状态的<item>,再让fillColor="@color/icon_state"。这样矢量图就能像普通控件一样响应交互状态,而无需在代码里手动改色。
三、与strokeColor的协作及常见误区
path节点除了fillColor还有strokeColor和strokeWidth,分别控制描边颜色和描边宽度。如果一个path只写了strokeColor没写fillColor,按照SVG规范,fill默认值是none,也就是不填充,只画边框。很多初学者以为写了pathData就会自动填色,结果图形看起来“空心”,其实就是漏了fillColor。
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- 只描边不填充 -->
<path
android:strokeColor="#000000"
android:strokeWidth="2"
android:pathData="M2,12 L22,12"/>
<!-- 既填充也描边 -->
<path
android:fillColor="#00FF00"
android:strokeColor="#000000"
android:strokeWidth="1"
android:pathData="M12,2 L12,22"/>
</vector>
从示例可以看到,第一个path因为没有fillColor,仅显示一条黑线;第二个path同时具备填充和描边,呈现出带黑边的绿色竖线。在复杂图标中,常常多个path叠加,有的负责填充、有的负责线条,这时每个path的fillColor都要单独设置,不能指望父级vector统一上色。
还有一个容易忽略的点:当fillColor引用了不存在的颜色资源,或者十六进制格式写错(比如少写一位),编译可能不报错,但运行后该path直接不渲染。因此填写颜色时务必检查位数与资源名称,尤其在复制设计工具导出的XML时,要留意工具可能使用了非Android支持的色彩函数。
四、低版本兼容与最佳实践
Vector Drawable在Android 5.0(API 21)才原生支持。如果项目最低版本低于21,需要在build.gradle中开启vectorDrawables.useSupportLibrary = true,并在布局或代码里通过AppCompatResources来获取drawable,这样fillColor等属性才能正确生效。否则在老机器上可能整个图形空白。
android {
defaultConfig {
vectorDrawables {
useSupportLibrary = true
}
}
}
开启兼容库后,在Java或Kotlin中应使用AppCompatResources.getDrawable(context, R.drawable.ic_sample)来加载,而不是普通的getDrawable。在XML布局里,使用app:srcCompat来引用矢量图,而不是android:src,从而确保填充色等所有矢量特性都被支持库解析。
总结来说,fillColor在Android vector path里就是决定形状内部颜色的属性。日常开发优先用@color或?attr引用,减少硬编码;多path图形逐个检查填充设置;低版本务必走兼容库。把这些细节处理好,矢量图就能在不同设备与主题下稳定呈现预期色彩。
Androidvector_pathfillColor修改时间:2026-08-01 19:09:37