The simplest way to solve this problem, if you want to change minor things like fill/stroke color or stroke width at runtime, is two have two versions of the same vector image with these changes, for example, one of them has only stroke color and the other one is filled:
ic_heart_stroked.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:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"
android:strokeWidth="1"
android:strokeColor="#000" />
</vector>
ic_heart_filled.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:fillColor="#FF000000"
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
</vector>
Then in your code, switch between the two files when the user clicks:
ibWhishlist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ibWhishlist.setImageResource(R.drawable.ic_heart_filled);
}
});
Another way is to use one of the ready-made libraries.
RichPathAnimator is one of the best libraries, it supports changing vector color, stroke width, and even animate vector graphics at runtime.
How to use it?
First, add the library dependency to your app build.gradle. Then in your vector.xml
give a name to the path that you want to change so:
<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="heartPath1"
android:fillColor="#00000000"
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"
android:strokeWidth="1"
android:strokeColor="#000" />
</vector>
In your layout replace Imagebutton
with com.richpath.RichPathView
and inside the vector, attribute pass your vector resource in that tag:
<com.richpath.RichPathView
android:id="@+id/heartView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:vector="@drawable/ic_heart" />
In your Activity
get a reference to the richpathview
then call findRichPathByName(YOUR_PATH_NAME)
RichPathView heartView = findViewById(R.id.heartView);
//Providing the path name that you add to your vector,
//in our example it's 'heartPath1'.
RichPath path= heartView.findRichPathByName("heartPath1");
//Set on heart path click listener.
path.setOnPathClickListener(new RichPath.OnPathClickListener() {
@Override
public void onClick(RichPath richPath) {
//Change the path color.
richPath.setFillColor(Color.RED);
//Change stroke width to zero.
richPath.setStrokeWidth(0);
}
});
If you don't want to use RichPathView
instead of your ImageView
or ImageButton
, and you want to change some things in your vector path, then consider using VectorChildFinder.