对于给定的视图下意见安卓PorterDuff色彩效果视图、色彩、效果、意见

2023-09-05 00:23:05 作者:琉璃繁缕

是否有可能在Android中建立一个视图,它适用于一些彩色滤光片的一切低于在其边界可见的一种方式?像在本实施例

Is it possible in android to set up a view in a way that it applies some color filter to everything below that's visible in its bounds? Like in this example:

只是一个简单的矩形认为反转它下面的一切颜色。当然,当用户滚动列表它也反映在倒箱。有一些简单的方法使用彩色滤光片,PorterDuff模式,这样做等?

Just a simple rectangular view that inverts colors of everything below it. Of course when user scrolls the list it is also reflected in the inverted box. Is there some easy way to do it using color filters, PorterDuff modes, etc?

推荐答案

您正在尝试使用一个视图层次结构是这样来解决这个问题:

You're trying to solve this problem using a view hierarchy like this:

父 在ListView控件 InverterView

但问题是,在这个位置上, InverterView 拥有怎样的ListView 绘制无法控制。但是你知道谁做有对如何的ListView 绘制控制? 的ListView 的父布局一样。换句话说,你真正想要的是一个层次是这样的:

Problem is, in this position, InverterView has no control over how ListView is drawn. But you know who does have control over how ListView is drawn? ListView's parent layout does. In other words, what you really want is a hierarchy like this:

父 在InverterLayout 在ListView控件

现在 InverterLayout 负责制定的ListView ,并能应用效果吧。

Now InverterLayout is responsible for drawing ListView, and can apply effects to it.

class InverterLayout extends FrameLayout
{
    // structure to hold our color filter
    private Paint paint = new Paint();
    // the color filter itself
    private ColorFilter cf;
    // the rectangle we want to invert
    private Rect inversion_rect = new Rect(100, 100, 300, 300);

    public InverterLayout(Context context)
    {
        super(context);
        // construct the inversion color matrix
        float[] mat = new float[]
        {
            -1,  0,  0, 0,  255,
             0, -1,  0, 0,  255,
             0,  0, -1, 0,  255,
             0,  0,  0, 1,  0
        };
        cf = new ColorMatrixColorFilter(new ColorMatrix(mat));
    }

    @Override protected void dispatchDraw(Canvas c)
    {
        // create a temporary bitmap to draw the child views
        Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
        Canvas cc = new Canvas(b);
        // draw them to that temporary bitmap
        super.dispatchDraw(cc);
        // copy the temporary bitmap to screen without the inversion filter
        paint.setColorFilter(null);
        c.drawBitmap(b, 0, 0, paint);
        // copy the inverted rectangle
        paint.setColorFilter(cf);
        c.drawBitmap(b, inversion_rect, inversion_rect, paint);
    }
}

在用这个,确保你的孩子认为有自己的背景。如果视图是透明和窗口背景示出了通过,该窗口背景不会被反转,因为 InverterLayout 有超过窗口的绘制没有控制权。

When using this, ensure your child view has its own background. If the view is transparent and the window background shows through, that window background will not be inverted, because the InverterLayout has no control over how the window is drawn.