Reputation: 1849
I have created the following vector asset and inserted it into an Imagebutton
.
I had like that the heart will change its color to red once it was clicked and return to transparent once it was clicked again.
I couldn't find any place that describes how to change the color of the whole heart. The closest solution I found was:
ibWhishlist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ibWhishlist.setColorFilter(getResources().getColor(R.color.colorRed));
}
});
However, it changes only the border of the heart and not the whole shape.
Thank you
SOLUTION:
Eventually what I used to solve this problem is to create as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="@drawable/ic_favorite_red_24dp" />
<item
android:drawable="@drawable/ic_favorite_black_24dp" />
</selector>
and inside my code:
ibWhishlist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ibWhishlist.setSelected(!ibWhishlist.isSelected());
if (ibWhishlist.isSelected()) {
//Handle selected state change
} else {
//Handle de-select state change
}
}
});
Upvotes: 1
Views: 6006
Reputation: 5217
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.
Upvotes: 4
Reputation: 371
public static Drawable updateDrawableVector(int resId, Context context, int color) {
Drawable drawable = context.getResources().getDrawable(resId);
drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
return drawable;
}
Upvotes: 0
Reputation: 571
Programmatically you can change the color of vector icon, but you can use only a single color. Since in your case heart icon filling background color, that's why your code is changing the border of icon.
you can take 2 vectors drawable to solve your problem (just one possibility)
You can check this link as well, How to change color of vector drawable path on button click
Upvotes: 0