setColorFilter似乎不适用于kitkat

时间:2015-07-27 21:10:32

标签: android android-5.0-lollipop android-drawable android-4.4-kitkat

我正在尝试使用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();

这里的mutateinvalidateSelf来电似乎没有对这个问题产生任何影响,只是将它们作为试图弄清楚发生了什么的一部分的例子。< / p>

FWIW,我使用drawable作为LayerDrawableStateListDrawable的一部分,用作按钮的背景或ImageView的可绘制结果无论哪种方式都是一致的(即,在kitkat上是错误的)。我也尝试将图标drawable直接放入StateListDrawable,而不会改变行为。在所有情况下,它在棒棒糖上都能正常工作,但在kitkat上不起作用。

作为一项实验,我将Drawable中的有色StateListDrawableLayerDrawable中取出,而不是StateListDrawable,它按预期工作。显然KitKat的{{1}}实现存在一些缺陷,导致它无法正常工作,这在以后的版本中得到了补救。

2 个答案:

答案 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开发很陌生,并且可以感谢他在展示我需要的部分之前简化它们。