android - setColorFilter 似乎不适用于 kitkat

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

我正在尝试使用 setColorFilter 为图形着色。以下代码似乎在 Lollipop 上运行良好,但似乎对 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 调用似乎对这里的问题没有任何影响,只是将它们作为已尝试解决的部分示例了解发生了什么。

FWIW,我将 drawable 用作 StateListDrawableLayerDrawable 的一部分,它被用作按钮的背景或 的 drawable code>ImageView 无论哪种方式,结果都是一致的(即,在 kitkat 上是错误的)。我还尝试再次将可绘制图标直接放入 StateListDrawable 中,但行为没有任何变化。在所有情况下,它都适用于 Lollipop ,但不适用于 kitkat。

作为实验,我从 StateListDrawable 而不是 LayerDrawable 中取出了着色的 Drawable 并且它按预期工作。显然,KitKat 对 StateListDrawable 的实现存在某些缺陷,导致其无法正常工作,但已在更高版本中修复。

最佳答案

最终,问题似乎是 KitKat 不支持在 Drawable 上使用 ColorFilter(或隐含的 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);
}

关于android - setColorFilter 似乎不适用于 kitkat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31663382/

相关文章:

java - 日历卡住 - 为什么?

android - 在 Android 应用程序中显示未接来电 Toast

java - 如何在android蓝牙通讯中写一个字符?

android - setBackgroundResource 和 setBackgroundDrawable 有什么区别

Android 形状错误在哪个 Android 版本上

java - Android - 异步网络调用 - 相互依赖的响应

Android Lollipop 首选项

android - 如何避免我的应用程序在三星设备上进入优化

android - API 21生成 key 对时无法生成证书异常

java - 使用通用绘图更改按钮的颜色状态