Android:如何通过代码修改Drawable中指定Path的颜色?
修改Vector Drawable中单个Path的颜色(保持其他Path颜色不变)
问题说明
我有如下Vector Drawable:
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16"> <path android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" android:fillColor="#1c1c1c" /> <path android:pathData="m6.7,12 l-3.7,-3.3 1.3,-1.5 2.3,2 4.9,-5.3 1.5,1.3z" android:fillColor="#fff" /> </vector>
默认显示为深灰色圆形内带白色对勾。
需求:通过代码修改圆形(第一个path)的填充色,同时保持对勾为白色。
遇到的问题:尝试marker.setTint(tintColor)和不同PorterDuff.Mode组合后,要么对勾颜色被改变,要么圆形颜色正确但显示出Vector的方形轮廓。
解决方案
方法1:直接修改Vector内部指定Path的颜色
通过VectorDrawableCompat获取内部Path,精准修改目标路径的填充色:
// 假设你的ImageView实例为markerImageView val drawable = markerImageView.drawable.mutate() as? VectorDrawableCompat ?: return // 获取第一个Path(对应圆形) val paths = drawable.paths if (paths.isNotEmpty()) { paths[0].fillColor = ContextCompat.getColor(context, R.color.your_target_color) markerImageView.invalidate() }
注:调用
mutate()是为了确保Drawable可修改,避免影响其他复用该Drawable的控件。
方法2:拆分Drawable为两层叠加
把原Vector拆成两个独立的Drawable,通过布局叠加实现独立控制:
- 新建
circle_bg.xml(仅保留圆形路径):
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16"> <path android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" android:fillColor="#1c1c1c" /> </vector>
- 新建
check_icon.xml(仅保留对勾路径):
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16"> <path android:pathData="m6.7,12 l-3.7,-3.3 1.3,-1.5 2.3,2 4.9,-5.3 1.5,1.3z" android:fillColor="#fff" /> </vector>
- 布局中用
FrameLayout叠加两个ImageView:
<FrameLayout android:layout_width="16dp" android:layout_height="16dp"> <ImageView android:id="@+id/circleBg" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/circle_bg"/> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/check_icon"/> </FrameLayout>
- 代码中仅修改圆形背景的颜色:
circleBg.setColorFilter(ContextCompat.getColor(context, R.color.your_target_color), PorterDuff.Mode.SRC_IN)
原方法失效原因
setTint()是对整个Drawable应用全局颜色滤镜,会影响所有Path;而各类tintMode无法精准区分不同Path,且Vector的绘制范围是方形,因此会出现方形轮廓的问题。
内容的提问来源于stack exchange,提问作者No_Name
相关产品推荐
相关产品推荐

