我正在尝试使用setColorFilter
为图形着色。以下代码似乎在棒棒糖上工作正常,但它似乎对kitkat没有影响,图标以其原始颜色呈现:
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();
这里的mutate
和invalidateSelf
来电似乎没有对这个问题产生任何影响,只是将它们作为试图弄清楚发生了什么的一部分的例子。< / p>
FWIW,我使用drawable作为LayerDrawable
中StateListDrawable
的一部分,用作按钮的背景或ImageView
的可绘制结果无论哪种方式都是一致的(即,在kitkat上是错误的)。我也尝试将图标drawable直接放入StateListDrawable
,而不会改变行为。在所有情况下,它在棒棒糖上都能正常工作,但在kitkat上不起作用。
作为一项实验,我将Drawable
中的有色StateListDrawable
从LayerDrawable
中取出,而不是StateListDrawable
,它按预期工作。显然KitKat的{{1}}实现存在一些缺陷,导致它无法正常工作,这在以后的版本中得到了补救。
答案 0 :(得分:4)
最终,似乎问题是KitKat不支持在ColorFilter
上使用Drawable
(或隐含的alpha),而StateListDrawable
又会Drawable
}。我的解决方案是使用相同的代码来构造复杂的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);
}
:
{{1}}
答案 1 :(得分:4)
我没有将着色附加到“禁用”状态(如在接受的答案中),而是通过专注于重新着色来让答案更简单,让我的用法利用如何在{{中包含现在着色的图像1}}。 (仅供参考,我试图翻译我正在使用的Xamarin C#,但下面的代码可能无法正确编译为Java)
StateListDrawable
最后,公平地对待接受的答案,我对Android开发很陌生,并且可以感谢他在展示我需要的部分之前简化它们。