Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

programmatically update android Vector Drawable

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)

like image 584
Jason Porter Avatar asked Mar 01 '15 06:03

Jason Porter


People also ask

How do I change vector icon color in android programmatically?

Tere is need to Change fillColor of a vector drawable in android programmatically, you can edit fill Color of a vector-file in Android programmatically using DrawableCompat. setTint() method which change tint color of whole vector drawable. Here, ImageView is set with drawable vector icon of black color.

What is not an advantage of using vector Drawables?

The drawback is that they might take longer to draw, etc since there's more of parsing and drawing going on than just using a bitmap. This should although be neglectable if you keep your vectors simple.

What is android PathData?

PathData in vector images android is Vector graphic program's script. It is not exactly clean and human readable code as a high priority.

How do I change the color of a vector asset?

If you're using a vector drawable in an ImageButton, just choose your color in android:tint . android:tint works on all android versions since APIv1. What you mean is drawableTint.


1 Answers

In short:

  1. You don't have a direct access to the inner elements in VectorDrawable.
  2. AnimatedVectorDrawable only has access to inner elements.
  3. 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 to mutate the object first.
like image 108
Eyal Biran Avatar answered Sep 20 '22 14:09

Eyal Biran