ViewGroup

时间:2015-09-07 16:26:09

标签: android canvas drawing porter-duff

我创建了一个可以水平滚动的视图(通过ViewGroup)。在左侧,我有行的图像(标题的种类)。当我将视图向左滚动时,我的项目会在行标题下移动。因为我在标题上有透明的背景,所以我看到了这个标题下的项目。我想删除标题下的部分项目。 在绘制标题之前,我试图通过Paint with PorterDuff.Mode.CLEAR在drawChild方法中绘制rects。结果我在标题下有黑色的字幕。 我发现了一些相同的问题,但在其他方面:

https://code.google.com/p/android/issues/detail?id=54105#c1

Android Paint PorterDuff.Mode.CLEAR drawing black color on my view

但是我找不到解决这个问题的方法。据我所知,在使用PorterDuff.Mode.CLEAR之前必须绘制一些其他位图。在我的情况下,我不能这样做。在我看来,我可以擦除(在我的情况下是透明的)一些矩形吗?

修改

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    if(isTitle(child)){
        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        Rect rect=new Rect(child.getLeft(),child.getTop(),child.getRight(),child.getBottom());

        canvas.drawRect(rect,paint);
    }
    return super.drawChild(canvas, child, drawingTime);
}

我也看到了这个方法,但它根本没有改变我的布局:

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    if(isTitle(child)){
        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        Bitmap b = Bitmap.createBitmap(child.getWidth(), child.getHeight(), Bitmap.Config.ARGB_8888);

        canvas.drawBitmap(b, child.getLeft(),child.getTop(), paint);
        b.recycle();
    }
    return super.drawChild(canvas, child, drawingTime);
}

编辑2 。试过saveLayer:

        Paint paint = new Paint();
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        RectF rect=new RectF(child.getLeft(),child.getTop(),child.getRight(),child.getBottom());
        int a = canvas.saveLayer(rect, paint, Canvas.ALL_SAVE_FLAG);
        canvas.drawRect(rect,paint);
        canvas.restoreToCount(a);

编辑3

enter image description here

我有可以向左,向右,向上和向下滚动的视图。此视图在顶部和左侧包含两种类型的标题,我有可以是不同大小的项目。当我添加所有这些项目以查看我之后添加项目我添加标题,在这种情况下,标题将始终绘制在项目前面。当用户向左/向上滚动时,项目将转到左侧/顶部,但标题将保留在其位置,此项目将位于标题下方。当我有标题的背景时,它没关系,因为用户没有看到标题下的项目,但现在我没有背景,用户看到标题下的项目。这就是为什么我试图使用drawChild(它调用每个项目)来删除标题下的部分项目。但是,如果我使用

canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);                       
draw_whatever_you_want(canvas); 
canvas.drawRect(rect, clearPaint); 
canvas.restore();

我必须将它用于所有物品。我在drawChild中的代码

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    if(!isTitle(child)){
        int left   = child.getLeft();
        int top    = child.getTop();
        int width  = getLeftHeaderWidth();
        int height = getTopHeaderHeight();
        if(left < width) {
            RectF rect = new RectF(0, 0, width, getHeight());
            canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
            boolean result = super.drawChild(canvas, child, drawingTime);
            canvas.drawRect(rect, mClearPaint);
            canvas.restore();
            return result;
        } else if(top < height) {
            RectF rect = new RectF(0, 0, getWidth(), height);
            canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
            boolean result = super.drawChild(canvas, child, drawingTime);
            canvas.drawRect(rect, mClearPaint);
            canvas.restore();
            return result;
        } else{
            return super.drawChild(canvas, child, drawingTime);
        }
    }else {
        return super.drawChild(canvas, child, drawingTime);
    }
}

1 个答案:

答案 0 :(得分:2)

我认为你在@Override protected boolean drawChild尝试的不是最好的事情,我只会做以下事情:

@Override
protected void dispatchDraw(Canvas canvas) {
    canvas.save(); // it saves the current clip, if not use CLIP_SAVE_FLAG
    canvas.clipRect(childrenRect)
    super.dispatchDraw(canvas); // draw your clipped children
    canvas.restore(); // now no clip
    draw_your_headers(canvas);
}