在Android 4上打破了setColorFilter(),在Android 5上工作

Ric*_*ier 12 android android-4.0-ice-cream-sandwich android-5.0-lollipop

我试图定期(每秒几次)在屏幕上闪烁不同的颜色.

要更改颜色,我Drawable.setColorFilter(int color, Mode mode)在主视图的背景上使用:

  • myView.getBackground().setColorFilter(Color.RED, PorterDuff.Mode.SRC);

出于调试目的,我添加了另一个我改变使用的视图 View.setBackgroundColor(int color).

问题是,setColorFilter()呼叫工作棒棒糖,但在以前的版本中碎(具体的Nexus 7 v4.4.4,Galaxy Nexus的V4.2.1).


我把颜色改变代码称为一个Runnable由a定期触发的代码Handler.

在所有平台上调用处理程序(我可以看到由于调试setBackgroundColor()调用而导致的后台更改).

以下是颜色循环代码:

Handler mHandler;
RunnableOnTick thisRunnable;
View vDebug;
View vBroken;

class RunnableOnTick implements Runnable
{
    int backgroundColor;

    @Override
    public void run()
    {
        color = random.nextInt(2);

        switch (color)
        {
            case 0:
            {
                backgroundColor = Color.RED;
                break;
            }
            case 1:
            {
                backgroundColor = Color.GREEN;
                break;
            }
        }

        // this works on all platforms
        vDebug.setBackgroundColor(backgroundColor);

        // this works only on Lollipop
        vBroken.getBackground().setColorFilter(backgroundColor, PorterDuff.Mode.SRC);
        vBroken.invalidate();

        mHandler.postDelayed(thisRunnable, 100);
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了不同的PorterDuff.Mode值 - 仍然无法让它在Android 4上运行.

Android v4和v5之间有什么不同会改变方式setColorFilter()

Har*_*rma 6

最终,似乎问题是KitKat不支持在Drawable上使用ColorFilter(或隐式的alpha),而Drawable又将在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);
}
Run Code Online (Sandbox Code Playgroud)


小智 -4

/**
     * Tint / Colorise the Supplied {@code drawable} into another color of supplied {@code colorResId}
     * @param context
     * @param drawable
     * @param colorResId
     * @return
     */
    public Drawable tintThisDrawable(Context context ,Drawable drawable,@ColorRes int colorResId)
    {
        Resources res = context.getResources();
        int color = res.getColor(colorResId);
        if (drawable != null) {
            drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
        }
        return drawable;
    }
Run Code Online (Sandbox Code Playgroud)

我记得这个函数在我的项目中的某个地方工作。请您自己测试一下。