I have a VectorDrawable consists of 9 rectangles. This is defined as an XML in the the drawables folder. I have this set as the background for an ImageView that I have declared in xml. android:src="@drawable/squares00"
I would like to change the color of one or more of the squares programatically at run time. I know there is way to do this using VectorDrawable animations. But I was wondering if there is simpler way of accessing my vectorDrawable in java, updating its properties (setting one or more of the fill colors for the rectangles) and then having the image background be updated with the updated VectoDrawable. My target is Android API 21 (lollipop)

- 37,241
- 25
- 195
- 267

- 461
- 1
- 4
- 8
-
3have u got the ans ? – Shreeshesh Apr 22 '15 at 07:29
-
You either need to use multiple drawables or have the single drawable be animatable. Why don't you want to use AnimatedVectorDrawable? – Andrew Flynn Aug 14 '15 at 01:31
-
post your custom drawable. that will help us. – Hiren Dabhi Aug 14 '15 at 06:46
-
please check [this](http://stackoverflow.com/a/35738726/2826147) answer. – Amit Vaghela Mar 02 '16 at 05:36
3 Answers
In short:
- You don't have a direct access to the inner elements in VectorDrawable.
- AnimatedVectorDrawable only has access to inner elements.
- Use AnimatedVectorDrawable to simulate what you need.
Long:
1. You don't have access
Looking at the source code for VectorDrawable will show that the inner elements information is stored in an inner private state class VectorDrawableState
. The only method to expose the inner element by name is getTargetByName
, but unfortunately it is package private (default) - you can't use it (unless you use reflection).
2. AnimatedVectorDrawable only has access
getTargetByName
is only being used by AnimatedVectorDrawable, as we can find by searching for usages of the method.
3. Use AnimatedVectorDrawable
So now that we see that this is the only available option, for example, we can try the following to change the color of element "rect2" from white to black:
change_color.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="0"
android:propertyName="fillColor"
android:valueFrom="@color/white"
android:valueTo="@color/black"/>
</set>
animation.xml:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vectordrawable" >
<target
android:name="rect2"
android:animation="@anim/change_color" />
</animated-vector>
and use the approach described here.
Note
If the above is still not an option for you, you can try the following:
- Copy the entire VectorDrawable and tweak it (not tested)
- Use reflection for
getTargetByName
to get the inner element. You will need to make sure tomutate
the object first.

- 5,656
- 1
- 28
- 29
-
I see the package private method you mentioned in VectorDrawable: `Object getTargetByName(String name) { return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); }` It looks like you are saying if I use this method, then I could theoretically perform an object animation on that object ("target") to change the color? What do you mean when you say I will need to `mutate` the object first? – Sam Edwards Aug 17 '15 at 19:40
-
1If you use reflection to for getTargetByName, you will be able to get an element defined in the XML by name. One example will be of type VFullPath - which is also a private class. You will need to manipulate it using reflection again on the mFillColor field (to change color). Regarding the mutate, you must call mutate() on the drawable itself - that will create a local copy of the inner state. Before you do that all the same drawables share the same backing data to improve performance. – Eyal Biran Aug 18 '15 at 07:26
-
Thanks @Eyal. That makes sense. Looking forward to when they expose a public API for this. I could try this reflection hack for now, but am using a Webview with RapahelJS for now as a workaround. Have you messed with the support library that they're developing for VectorDrawable to see if this would work on that as well? https://android.googlesource.com/platform/frameworks/support/+/master/v7/vectordrawable/ – Sam Edwards Aug 18 '15 at 16:27
-
Can you please show how to use reflection on VectorDrawable to change the color of a specific path? – android developer Mar 23 '23 at 08:13
Try this library https://github.com/devendroid/VectorChildFinder
val vector = VectorChildFinder(context, R.drawable.drawable_id, imageView)
vector.findPathByName("path_name").fillColor = Color.RED
<vector
...>
<path
android:name="path_name"
android:fillColor="#000"
android:pathData="..." />
</vector>

- 176
- 2
- 8