ViewGroup 中的黑色矩形 PorterDuff.Mode.CLEAR
Black rect PorterDuff.Mode.CLEAR in ViewGroup
我创建了一个可以水平滚动的视图(通过 ViewGroup)。在左侧,我有行的图像(一种标题)。当我向左滚动视图时,我的项目移动到行的标题下。因为我的标题背景是透明的,所以我看到了这个标题下的项目。我想删除标题下的部分项目。
在绘制标题之前,我尝试在 drawChild 方法中通过 Paint with PorterDuff.Mode.CLEAR 绘制矩形。结果我的标题下有黑色矩形。
我发现了一些相同的问题,但在其他情况下:
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。已尝试保存图层:
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
我有可以向左、向右、向上和向下滚动的视图。此视图在顶部和左侧包含 2 种类型的 header,我有可以不同大小的项目。当我将所有这些项目添加到视图时,我先添加项目,然后再添加 headers,在这种情况下,headers 将始终绘制在项目前面。当用户滚动 left/top 时,项目将转到 left/top 一侧,但 header 将留在其位置并且该项目将在 header 下方。当我有 headers 的背景时,没关系,因为用户没有看到 headers 下的项目,但现在我没有背景,用户看到 header 下的项目秒。这就是为什么我尝试使用 drawChild(调用每个项目)来擦除 headers 下的部分项目。但是如果我使用
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);
}
}
我认为你在 @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);
}
我创建了一个可以水平滚动的视图(通过 ViewGroup)。在左侧,我有行的图像(一种标题)。当我向左滚动视图时,我的项目移动到行的标题下。因为我的标题背景是透明的,所以我看到了这个标题下的项目。我想删除标题下的部分项目。 在绘制标题之前,我尝试在 drawChild 方法中通过 Paint with PorterDuff.Mode.CLEAR 绘制矩形。结果我的标题下有黑色矩形。 我发现了一些相同的问题,但在其他情况下:
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。已尝试保存图层:
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
我有可以向左、向右、向上和向下滚动的视图。此视图在顶部和左侧包含 2 种类型的 header,我有可以不同大小的项目。当我将所有这些项目添加到视图时,我先添加项目,然后再添加 headers,在这种情况下,headers 将始终绘制在项目前面。当用户滚动 left/top 时,项目将转到 left/top 一侧,但 header 将留在其位置并且该项目将在 header 下方。当我有 headers 的背景时,没关系,因为用户没有看到 headers 下的项目,但现在我没有背景,用户看到 header 下的项目秒。这就是为什么我尝试使用 drawChild(调用每个项目)来擦除 headers 下的部分项目。但是如果我使用
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);
}
}
我认为你在 @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);
}