13

在android中是否可以设置一个视图,将一些颜色过滤器应用于其边界内可见的所有内容?就像在这个例子中一样:

过滤视图

只是一个简单的矩形视图,它可以反转其下方所有内容的颜色。当然,当用户滚动列表时,它也会反映在倒置框中。有没有一些简单的方法可以使用滤色器、PorterDuff 模式等?

4

3 回答 3

14

您正在尝试使用如下视图层次结构解决此问题:

  • 家长
    • 列表显示
    • 逆变器视图

问题是,在这个位置,InverterView无法控制如何ListView绘制。但是你知道谁可以控制如何ListView绘制吗? ListView的父布局确实如此。换句话说,您真正想要的是这样的层次结构:

  • 家长
    • 逆变器布局
      • 列表显示

现在InverterLayout负责绘图ListView,并且可以对其应用效果。

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无法控制窗口的绘制方式。

于 2013-09-02T21:31:07.730 回答
1

如果我可以简单地发表评论,我会的,因为我不确定我在这里是否正确。所以买家要小心,这里是:

我认为您可以通过利用 View.OnDragEve[]ntListener 来实现这种效果。这是文档

我认为您应该调整android中使用的拖放触发器模型(即应用程序和操作系统之间的通信方式)。你如何调整它完全取决于你的应用程序中强制一个视图进入另一个视图边界的机制。一旦你弄清楚了,你就可以使用以下方法进行高级颜色魔法: ColorMatrixPorterDuffColorFilter和其他几个。

这对我来说听起来比替代Xfermode容易得多。祝你好运!

于 2013-08-29T03:52:58.747 回答
1

这是我要做的:

查看层次结构:

  • 相对布局(或框架布局)
    • 列表显示
      • 自定义逆变器视图

InverterView 通过 onTouchListener 中父视图(RelativeLayout)的 OnTouch 定位:

if (event.getAction() == MotionEvent.ACTION_MOVE)
           // Set Coordinates for the custom View.
           // Copy the bitmapCache of the ListView (jsut the portion you need
           // and send it to the customView.
           // Apply the filters you want.
           // Invalidate!

我使用这种方法实现了放大镜。它就像一个魅力。也许我可以稍后再发布一些代码,但我现在有点忙。

于 2013-09-03T07:20:35.783 回答