2

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

我要做的是在屏幕上的某个地方放置一个drawable,给它一个可以动态更改的花哨颜色并使其可点击(使用StateListDrawable)。

对于动态的颜色变化,我正在考虑使用 PorterDuffColorFilter ,我将其应用于可绘制对象。但是,将可绘制对象添加到 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 透明边框。

问题...

如果我只是添加原始可绘制对象,我会得到一个全黑图像,侧面有一些透明像素,如下所示:

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

这是结果:

我想要的结果,但没有滤色器

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

    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也会导致奇怪的结果:

也不好...

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

有谁知道为什么我会在图像的左右两侧得到奇怪的淡入淡出效果?

4

1 回答 1

0

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

如果你想在代码中做这一切很好,但在我看来,最好的组合是在 XML 中定义一个具有所述白色灰度背景的 TextView,然后在代码中你可以更改背景颜色:

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

可绘制的框可以是任何东西,PNG 或其他定义填充纯白色的矩形形状的 XML。

int onTheFlyColor = 0xAARRGGBB; or getResources().getColor(R.color.red);
TextView tv = findViewById(R.id.mybox);
tv.getBackground().setColorFilter(onTheFlyColor, Mode.MULTIPLY);
于 2013-05-02T19:40:23.410 回答