Skip to content

Instantly share code, notes, and snippets.

@seupedro
Created May 31, 2018 11:44
Show Gist options
  • Save seupedro/23e26806ea6a0706e32dc171b3f8bb23 to your computer and use it in GitHub Desktop.
Save seupedro/23e26806ea6a0706e32dc171b3f8bb23 to your computer and use it in GitHub Desktop.
How to change Icon color (Drawable, XML, whatever you want), on Android dynamically (programmatically, whatever)
// Explained Method
Drawable deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_delete);
Drawable deleteIconCompat = DrawableCompat.wrap(deleteIcon).mutate();
Drawable deleteIconMute = deleteIconCompat.mutate();
DrawableCompat.setTint(deleteIconMute, Color.RED);
// Compact Method
DrawableCompat.setTint(
DrawableCompat.wrap(
ContextCompat.getDrawable(context, R.drawable.ic_check).mutate()), Color.WHITE);
// Source: https://medium.com/@hanru.yeh/tips-for-drawablecompat-settint-under-api-21-1e62a32fc033
// By: Bram Yeh
@seupedro
Copy link
Author

Tips for DrawableCompat.setTint() Under API 21

To change image and icon’s color, we used to call Drawable.setColorFilter (int color, PorterDuff.Mode.SRC_ATOP) with color what we wanted. After DrawableCompat released setTint(Drawable drawable, int tint), we change to use DrawableCompat to change tint color.

DrawableCompat.wrap(Drawable drawable)

To make DrawableCompat.setTint(Drawable, int) work under API 21, we need to wrap original drawable.

Drawable drawable = ContextCompat.getDrawable(context, R.drawable.xxx);
Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(wrappedDrawable, ContextCompat.getColor(context, R.color.white));
Drawable.mutate()

Since Android optimized performance, by default, all drawables instances loaded from the same resource share a common state. When we modify the state of one instance, all the other instances will receive the same modification. So if we want not to affect other drawables, don’t forget to mutate the drawable via Drawable.mutate() before applying the filter. A mutable drawable is guaranteed to not share its state with any other drawables.

Drawable wrappedDrawable = DrawableCompat.wrap(drawable);
Drawable mutableDrawable = wrappedDrawable.mutate();
DrawableCompat.setTint(mutableDrawable, ContextCompat.getColor(context, R.color.white));
Drawable.invalidateSelf()

And for some devices, this still not worked. So you might need to call Drawable.invalidateSelf() to make drawable update.

by: Bram Yeh
Source: https://medium.com/@hanru.yeh/tips-for-drawablecompat-settint-under-api-21-1e62a32fc033

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment