Reputation: 10929
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.
Upvotes: 53
Views: 68218
Reputation: 1
This can be done through Java reflection. First reflect call VectorDrawable.getTargetByName or VectorDrawableCompat.getTargetByName method to get VFullPath:
Object path = ReflectUtil.invoke(vectorDrawable, "getTargetByName", new Class[]{String.class}, new Object[]{pathName});
Then Reflect calls the VFullPath.setFillColor method to set the color:
ReflectUtil.invoke(path, "setFillColor", new Class[]{int.class}, new Object[]{color});
Upvotes: 0
Reputation: 1
DrawableCompat.setTint(imageView.getDrawable(),ContextCompat.getColor(getApplicationContext(), R.color.colorAccent));
Upvotes: -2
Reputation: 699
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)
Upvotes: 7
Reputation: 3444
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
Upvotes: 46
Reputation: 66
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.
Upvotes: 5
Reputation: 89
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
Upvotes: 3
Reputation: 5888
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.
Upvotes: 61
Reputation: 1325
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.
Upvotes: 3
Reputation: 334
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).
Upvotes: 0