我有RecyclerView
GridLayoutManager
,其中包含各种ViewTypes
(和SpanSize
s)的项目。我需要为所有R.layout.item_image
类型设置圆角,如下图所示
所以我创建了一个ItemDecoration
来计算将要绘制这些项目的Rect
。然后将Canvas
剪切到此Rect
(使用Path
来圆角):
public class RoundCornersDecoration extends RecyclerView.ItemDecoration {
private final float radius;
private final RectF defaultRectToClip;
public RoundCornersDecoration(float radius) {
this.radius = radius;
defaultRectToClip = new RectF(Float.MAX_VALUE, Float.MAX_VALUE, 0, 0);
}
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
final RectF rectToClip = getRectToClip(parent);
// has no items with ViewType == `R.layout.item_image`
if (rectToClip.equals(defaultRectToClip)) {
return;
}
final Path path = new Path();
path.addRoundRect(rectToClip, radius, radius, Path.Direction.CW);
canvas.clipPath(path);
}
private RectF getRectToClip(RecyclerView parent) {
final RectF rectToClip = new RectF(defaultRectToClip);
final Rect childRect = new Rect();
for (int i = 0; i < parent.getChildCount(); i++) {
if (!isImage(parent, i)) {
continue;
}
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, childRect);
rectToClip.left = Math.min(rectToClip.left, childRect.left);
rectToClip.top = Math.min(rectToClip.top, childRect.top);
rectToClip.right = Math.max(rectToClip.right, childRect.right);
rectToClip.bottom = Math.max(rectToClip.bottom, childRect.bottom);
}
return rectToClip;
}
private boolean isImage(RecyclerView parent, int viewPosition) {
final RecyclerView.Adapter adapter = parent.getAdapter();
final int viewType = adapter.getItemViewType(viewPosition);
return viewType == R.layout.item_image;
}
}
除了图片下方没有其他项目外,一切正常。 我想这是因为我在实际绘制任何项目之前剪切了画布。那么我应该如何剪裁画布以保存圆角并覆盖所有其他项目?
答案 0 :(得分:0)
我终于找到了解决方案而且非常简单。我需要做的就是提供canvas
的其他部分:
正如您所见 top ,左和右点与第一个矩阵相同,因此我们只需找到< EM>底:
int maxBottom = 0;
final Rect childRect = new Rect();
for (int i = 0; i < parent.getChildCount(); i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, childRect);
maxBottom = Math.max(maxBottom, childRect.bottom);
}
创建一个新的矩形:
final RectF otherItemsRect = new RectF(rectToClip);
otherItemsRect.top = otherItemsRect.bottom;
otherItemsRect.bottom = maxBottom;
将其包含在Path
中,然后剪辑:
final Path path = new Path();
path.addRoundRect(rectToClip, radius, radius, Path.Direction.CW);
path.addRect(otherItemsRect, Path.Direction.CW);
canvas.clipPath(path);
就是这样。现在我们有所有带图像圆角的项目
附:我没有按照简单的顺序提供优化的代码