Change fillColor of a vector in android programmatically
This is exactly what you need. Credits to @emmaguy, the author of the post. I just added the full support of Support Library 23.4+, which enables you to stop generating pngs at runtime:
// Gradle Plugin 2.0+ android { defaultConfig { vectorDrawables.useSupportLibrary = true } }
And if this line is set on your Activity's or Application's onCreate:
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
You can use your SVGs not only with srcCompat
but also with other attributes such as drawableLeft
, background
, etc. in TextView, ToggleButton and so on. It also works if used on selectors.
Note: I modified the code to use VectorDrawableCompat.create
instead of ResourcesCompat.getDrawable
. Otherwise it would not work and throw org.xmlpull.v1.XmlPullParserException: Binary XML file line #2: invalid drawable tag vector
.
Medium post content:
First, we create attributes for the two kinds of bauble, so we can change their colours:
<declare-styleable name="ChristmasTree"> <attr name="bauble_round" format="color" /> <attr name="bauble_small" format="color" /></declare-styleable>
Then, in the VectorDrawable, set the parts we want to dynamically change to use these attributes:
<path android:fillColor="?attr/bauble_round" android:pathData="...." /><path android:fillColor="?attr/bauble_small" android:pathData="...." />...
Create themes and set the colours you want to use:
<style name="UpdatedScene" parent="DefaultScene"> <item name="bauble_round">#db486e</item> <item name="bauble_small">#22c7f7</item></style><style name="DefaultScene"> <item name="bauble_round">#fec758</item> <item name="bauble_small">#f22424</item></style>
Use the drawable in an ImageView:
final ContextThemeWrapper wrapper = new ContextThemeWrapper(this, R.style.DefaultScene);final Drawable drawable = VectorDrawableCompat.create(getResources(), R.drawable.christmas, wrapper.getTheme());imageView.setImageDrawable(drawable);
That’s it! When you want to change the colours, simply set a different theme and your drawable will update.See the GitHub repo for a full sample.
If you want to change the whole color, you could apply a PorterduffColorFilter.But this does not work for a single <path>
. Only for the whole drawable.
public void applyThemeToDrawable(Drawable image) { if (image != null) { PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP); image.setColorFilter(porterDuffColorFilter); }}
VectorDrawable extends the Drawable class. See Docs
add setColorFilter()
method to your image content vector (is added in api level 8) like this:
imgshare = (Imageview) findviewbyId(R.id.imageshare);imgshare.setColorFilter(color);