I'm attempting to colorize a graphic using setColorFilter
. The following code seems to work fine on lollipop, but it seems to have no effect on kitkat, the icon is rendered in it's original colors:
Drawable icon = ContextCompat.getDrawable(context, R.drawable.ic_chat_button).mutate();
icon.setColorFilter(context.getResources().getColor(R.color.control_tint_color), PorterDuff.Mode.SRC_ATOP);
icon.invalidateSelf();
The mutate
and invalidateSelf
calls don't seem to have any effect on the problem here, just leaving them in as an example of part of what's been tried to figure out what's going on.
FWIW, I'm using the drawable as part of a LayerDrawable
in a StateListDrawable
that gets used as either the background for a button or as the drawable for an ImageView
The results are consistent (ie., wrong on kitkat) either way. I've also tried putting the icon drawable directly into the StateListDrawable
again with no change in behavior. In all cases, it works fine on lollipop, but doesn't work on kitkat.
As an experiment, I took the tinted Drawable
out of the StateListDrawable
but not the LayerDrawable
and it works as expected. Apparently there's something flawed in KitKat's implementation of StateListDrawable
that prevents it from working, that has been remedied in later versions.
Ultimately, it seems like the problem is that KitKat doesn't support using a ColorFilter
(or implicitly an alpha) on a Drawable
that will in turn be in a StateListDrawable
. My solution was to use the same to code to construct the complex Drawable
and then render that into a simple BitMapDrawable
:
static Drawable createDrawable(Context context, int color, boolean disabled) {
OvalShape oShape = new OvalShape();
ShapeDrawable background = new ShapeDrawable(oShape);
background.getPaint().setColor(color);
ShapeDrawable shader = new ShapeDrawable(oShape);
shader.setShaderFactory(new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
return new LinearGradient(0, 0, 0, height,
new int[]{
Color.WHITE,
Color.GRAY,
Color.DKGRAY,
Color.BLACK
}, null, Shader.TileMode.REPEAT);
}
});
Drawable icon = ContextCompat.getDrawable(context, R.drawable.ic_chat_button).mutate();
icon.setColorFilter(context.getResources().getColor(R.color.control_tint_color), PorterDuff.Mode.SRC_IN);
Drawable layer = new LayerDrawable(new Drawable[]{ shader, background, icon });
layer.setAlpha(disabled ? 128 : 255);
// Note that on KitKat, setting a ColorFilter on a Drawable contained in a StateListDrawable
// apparently doesn't work, although it does on later versions, so we have to render the colored
// bitmap into a BitmapDrawable and then put that into the StateListDrawable
Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
layer.setBounds(0, 0, layer.getIntrinsicWidth(), layer.getIntrinsicHeight());
layer.draw(canvas);
return new BitmapDrawable(context.getResources(), bitmap);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With