首页 文章

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

提问于
浏览
2

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

我要做的就是在屏幕上放置一个可绘制的颜色,给它一个可以随时改变的奇特颜色并使其可点击(使用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

    要应用滤色器并更改可绘制的颜色,我发现使用灰度/白色的基本可绘制最好与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);
    

相关问题