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)
In short:
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:
getTargetByName
to get the inner element. You will need to make sure to mutate
the object first.