Skip to content

Instantly share code, notes, and snippets.

@NikolayKul
Last active May 24, 2018 09:08
Show Gist options
  • Save NikolayKul/67450c10d443fe680f73f896211a7d3d to your computer and use it in GitHub Desktop.
Save NikolayKul/67450c10d443fe680f73f896211a7d3d to your computer and use it in GitHub Desktop.
/*
Related SO question: https://stackoverflow.com/questions/47990179/round-corners-itemdecoration/48003946
*/
public class AttachmentMediaCornersDecoration extends RecyclerView.ItemDecoration {
private final float radius;
private final RectF defaultRectToClip;
private final List<Integer> allowedViewTypes = Arrays.asList(
AttachmentImageViewItem.VIEW_TYPE,
AttachmentVideoViewItem.VIEW_TYPE,
AttachmentBlurViewItem.VIEW_TYPE);
public AttachmentMediaCornersDecoration(Context context, @DimenRes int radiusRes) {
defaultRectToClip = new RectF(Float.MAX_VALUE, Float.MAX_VALUE, 0, 0);
radius = radiusRes != 0
? context.getResources().getDimension(radiusRes)
: 0f;
}
@Override
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
float maxBottom = 0f;
final RectF roundRect = new RectF(defaultRectToClip);
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);
if (isMedia(parent, i)) {
roundRect.left = Math.min(roundRect.left, childRect.left);
roundRect.top = Math.min(roundRect.top, childRect.top);
roundRect.right = Math.max(roundRect.right, childRect.right);
roundRect.bottom = Math.max(roundRect.bottom, childRect.bottom);
}
}
// has no `allowedViewTypes`
if (roundRect.equals(defaultRectToClip)) {
return;
}
// used to draw other attachments on canvas after clipping (below `roundRect`)
final RectF otherRect = new RectF(roundRect);
otherRect.top = otherRect.bottom;
otherRect.bottom = maxBottom;
final Path path = new Path();
path.addRoundRect(roundRect, radius, radius, Path.Direction.CW);
path.addRect(otherRect, Path.Direction.CW);
canvas.clipPath(path);
}
private boolean isMedia(RecyclerView parent, int viewPosition) {
final RecyclerView.Adapter adapter = parent.getAdapter();
final int viewType = adapter.getItemViewType(viewPosition);
return allowedViewTypes.contains(viewType);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment