How to change color of vector drawable path on button click

AndroidVectorVector GraphicsAndroid Vectordrawable

Android Problem Overview


With the new android support update, vector drawables get backward compatibility. I have a vector image with various paths. I want the color of the paths to change on click of a button or programmatically based on an input value. Is it possible to access the name parameter of the vector path? And then change the color.

Android Solutions


Solution 1 - Android

The color of the whole vector can be changed using setTint.

You have to set up your ImageView in your layout file as this:

<ImageView
    android:id="@+id/myImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:tint="@color/my_nice_color"
    android:src="@drawable/ic_my_drawable"
    android:scaleType="fitCenter" />

Then to change the color of your image:

DrawableCompat.setTint(myImageView.getDrawable(), ContextCompat.getColor(context, R.color.another_nice_color));

Note: myImageView.getDrawable() gives nullpointerexception if the vector drawable is set to the imageView as background.

Solution 2 - Android

Use this to change a path color in your vector drawable

VectorChildFinder vector = new VectorChildFinder(this, R.drawable.my_vector, imageView);

VectorDrawableCompat.VFullPath path1 = vector.findPathByName("path1");
path1.setFillColor(Color.RED); 

Library is here: https://github.com/devsideal/VectorChildFinder

Solution 3 - Android

There are several ways of doing the same stuff, but this works for both Vector Drawables as well as SVG (Local/Network).

imageView.setColorFilter(ContextCompat.getColor(context, 
R.color.headPink), android.graphics.PorterDuff.Mode.SRC_IN);

(change R.color.headPink with color of your choice)

Solution 4 - Android

You can use this method to change color in lower API to change vector color in fragment

int myVectorColor = ContextCompat.getColor(getActivity(), R.color.colorBlack);
                    myButton.getIcon().setColorFilter(myVectorColor, PorterDuff.Mode.SRC_IN);

in place of getActivity you should use MainActivity.this for changing vector color in activity

Solution 5 - Android

You can change the color of individual path at runtime, without using reflection.

VectorMaster introduces dynamic control over vector drawables. Each and every aspect of a vector drawable can be controlled dynamically (via Java instances), using this library.

Just add the following dependency in your app's build.gradle

dependencies {
    compile 'com.sdsmdg.harjot:vectormaster:1.0.9'
}

In your case you need a simple color change:

Vector example: your_vector.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
<path
    android:name="outline"
    android:pathData="M20.84,4..."
    android:strokeColor="#5D5D5D"
    android:fillColor="#00000000"
    android:strokeWidth="2"/>

XML:

<com.sdsmdg.harjot.vectormaster.VectorMasterView
    android:id="@+id/your_vector"
    android:layout_width="150dp"
    android:layout_height="150dp"
    app:vector_src="@drawable/your_drawable" />

Java:

VectorMasterView heartVector = (VectorMasterView) 
findViewById(R.id.your_drawable);

// find the correct path using name
PathModel outline = heartVector.getPathModelByName("outline");

// set the stroke color
outline.setStrokeColor(Color.parseColor("#ED4337"));

// set the fill color (if fill color is not set or is TRANSPARENT, then no fill is drawn)
outline.setFillColor(Color.parseColor("#ED4337"));

From: https://github.com/harjot-oberai/VectorMaster, licensed under MIT.

You have now full control over vector drawables.

Solution 6 - Android

Check my answer on this other question: https://stackoverflow.com/a/38418049/1335438.

It is a great idea on how to manage this by using Themes and parameterizing the paths in order to be able to set them dynamically.

Solution 7 - Android

As stated by @Eyal in this post https://stackoverflow.com/a/32007436/4969047

You cannot change the color of individual path at runtime. Looking at the source code of VectorDrawableCompat, the only method to expose the inner element by name is getTargetByName which is present in inner private state class VectorDrawableCompatState of VectorDrawableCompat.

Since it is a package private (default) - you can't use it (unless you use reflection).

Solution 8 - Android

DrawableCompat.setTint(imageView.getDrawable(),ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsukuView Question on Stackoverflow
Solution 1 - AndroidMarco HernaizView Answer on Stackoverflow
Solution 2 - AndroidDevenView Answer on Stackoverflow
Solution 3 - AndroidMoonis AbidiView Answer on Stackoverflow
Solution 4 - AndroidArshdeep SinghView Answer on Stackoverflow
Solution 5 - AndroidJeRollView Answer on Stackoverflow
Solution 6 - AndroidsaiyancoderView Answer on Stackoverflow
Solution 7 - AndroidShubhralView Answer on Stackoverflow
Solution 8 - AndroidAnmol NeemaView Answer on Stackoverflow