在StateListDrawable中应用颜色过滤器不起作用

时间:2013-05-02 12:39:54

标签: android bitmap drawable colorfilter

我正在编写一个应用程序,我必须在其中进行一些即时的图像突变。

我要做的就是在屏幕上放置一个可绘制的颜色,给它一种奇特的颜色,可以动态改变并使其可点击(使用StateListDrawable)。

对于飞行中的颜色变化,我想使用一个PorterDuffColorFilter,我将它应用于drawable。然而,将Stateable添加到StateListDrawable似乎是个坏主意,因为滤色器被删除了。 但后来我提出了我在SO上找到的解决方案:

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap one = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_drawable, options);
    Bitmap oneCopy = Bitmap.createBitmap(one.getWidth(), one.getHeight(), Bitmap.Config.ARGB_8888);

    Canvas c = new Canvas(oneCopy);
    Paint p = new Paint();
    p.setColorFilter(new PorterDuffColorFilter(onTheFlyColorResId, PorterDuff.Mode.SRC_ATOP));
    c.drawBitmap(one, 0, 0, p);

    ...

    sld.addState(new int[]{-stateFocused}, new BitmapDrawable(context.getResources(), oneCopy));

这种作品,但有一件棘手的事情。下面的图像是结果,而R.drawable.my_drawable是一个PNG文件,其中包含3px透明边框的黑色。

The problem...

如果我只是添加原始的drawable,我会得到一个完整的黑色图像,侧面有一些透明的像素,如下所示:

    sld.addState(new int[]{-stateFocused}, context.getResources().getDrawable(R.drawable.my_drawable));

这就是结果:

The result I want but without the color filter

所以我认为oneCopy bitmat或画布上的绘图可能有问题,所以我将代码更改为:

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap one = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_drawable, options);

    ...

    sld.addState(new int[]{-stateFocused}, new BitmapDrawable(context.getResources(), one));

因此不再需要drawable的转换,只需将其作为位图读取并再次将其转换为drawable也会导致奇怪的结果:

Also not good...

我只想要的是第二张应用了我自定义颜色的图片。

有没有人知道为什么我会在图像的左右两侧产生奇怪的淡化效果?

1 个答案:

答案 0 :(得分:0)

要应用滤色镜并更改可绘制的颜色,我发现使用灰度/白色的基本可绘制最好与Mode.MULTIPLY PorterDuff滤镜结合使用。

如果你想在代码中完成所有这一切都很好,但在我看来,最佳组合是使用所述白色灰度背景在XML中定义TextView,然后在代码中可以更改背景颜色: / p>

<TextView
    android:id="@+id/mybox"
    . . . 
    android:background="@drawable/box"

box drawable可以是任何东西,PNG或其他XML,用于定义填充纯色白色的矩形形状。

int onTheFlyColor = 0xAARRGGBB; or getResources().getColor(R.color.red);
TextView tv = findViewById(R.id.mybox);
tv.getBackground().setColorFilter(onTheFlyColor, Mode.MULTIPLY);