I created a ViewGroup that extends RelativeLayout and adds support for rounded corners which you can find here: https://gist.github.com/jerrellmardis/9240278. This ViewGroup is used to display each cell in the grid. When the container initially displays all cells have nice rounded corners but as you scroll back and forth the some of the corners on the cells get clipped. Here's a couple screenshots to illustrate what I'm talking about.
The views that are affected seem a bit random. Here's my layout as well.
public class QuiltLayout extends FreeFlowLayoutBase implements FreeFlowLayout {
private Context mContext;
private HashMap<Object, FreeFlowItem> mProxies;
private int mLargeItemSide;
private int mRegularItemSide;
public QuiltLayout(Context context) {
mContext = context;
mProxies = new HashMap<Object, FreeFlowItem>();
}
@Override
public void setDimensions(int measuredWidth, int measuredHeight) {
super.setDimensions(measuredWidth, measuredHeight);
mRegularItemSide = mContext.getResources().getDimensionPixelSize(R.dimen.patch_width_1);
mLargeItemSide = mContext.getResources().getDimensionPixelSize(R.dimen.patch_width_2);
}
@Override
public void prepareLayout() {
mProxies.clear();
Section section = itemsAdapter.getSection(0);
final float regularHeightHRatio = .4f;
final float largeHeightHRatio = .6f;
int h1 = Math.round(height * regularHeightHRatio);
int h2 = Math.round(height * largeHeightHRatio);
int xOffset = 0;
for (int i = 0; i < section.getDataCount(); i++) {
FreeFlowItem freeFlowItem = new FreeFlowItem();
freeFlowItem.isHeader = false;
freeFlowItem.itemIndex = i;
freeFlowItem.itemSection = 0;
freeFlowItem.data = section.getDataAtIndex(i);
Rect r = new Rect();
switch (i % 18) {
case 0:
r.left = 0;
r.top = 0;
r.right = mLargeItemSide;
r.bottom = height;
break;
case 1:
r.left = 2 * mRegularItemSide;
r.top = 0;
r.right = r.left + mRegularItemSide;
r.bottom = h1;
break;
case 2:
r.left = 2 * mRegularItemSide;
r.top = h1;
r.right = r.left + mRegularItemSide;
r.bottom = height;
break;
case 3:
r.left = 3 * mRegularItemSide;
r.top = 0;
r.right = r.left + mLargeItemSide;
r.bottom = h2;
break;
case 4:
r.left = 3 * mRegularItemSide;
r.top = h2;
r.right = r.left + mRegularItemSide;
r.bottom = height;
break;
case 5:
r.left = 4 * mRegularItemSide;
r.top = h2;
r.right = r.left + mRegularItemSide;
r.bottom = height;
break;
case 6:
r.left = 5 * mRegularItemSide;
r.top = 0;
r.right = r.left + mRegularItemSide;
r.bottom = h1;
break;
case 7:
r.left = 5 * mRegularItemSide;
r.top = h1;
r.right = r.left + mLargeItemSide;
r.bottom = height;
break;
case 8:
r.left = 6 * mRegularItemSide;
r.top = 0;
r.right = r.left + mRegularItemSide;
r.bottom = h1;
break;
case 9:
r.left = 7 * mRegularItemSide;
r.top = 0;
r.right = r.left + mLargeItemSide;
r.bottom = height;
break;
case 10:
r.left = 9 * mRegularItemSide;
r.top = 0;
r.right = r.left + mRegularItemSide;
r.bottom = h2;
break;
case 11:
r.left = 9 * mRegularItemSide;
r.top = h2;
r.right = r.left + mRegularItemSide;
r.bottom = height;
break;
case 12:
r.left = 10 * mRegularItemSide;
r.top = 0;
r.right = r.left + mRegularItemSide;
r.bottom = h1;
break;
case 13:
r.left = 10 * mRegularItemSide;
r.top = h1;
r.right = r.left + mLargeItemSide;
r.bottom = height;
break;
case 14:
r.left = 11 * mRegularItemSide;
r.top = 0;
r.right = r.left + mRegularItemSide;
r.bottom = h1;
break;
case 15:
r.left = 12 * mRegularItemSide;
r.top = 0;
r.right = r.left + mLargeItemSide;
r.bottom = h2;
break;
case 16:
r.left = 12 * mRegularItemSide;
r.top = h2;
r.right = r.left + mRegularItemSide;
r.bottom = height;
break;
case 17:
r.left = 13 * mRegularItemSide;
r.top = h2;
r.right = r.left + mRegularItemSide;
r.bottom = height;
break;
}
r.offset(xOffset, 0);
freeFlowItem.frame = r;
mProxies.put(section.getDataAtIndex(i), freeFlowItem);
if (i % 18 == 17) xOffset += 14 * mRegularItemSide;
}
}
@Override
public HashMap<Object, FreeFlowItem> getItemProxies(int viewPortLeft, int viewPortTop) {
Rect viewport = new Rect(viewPortLeft, viewPortTop, viewPortLeft + width, viewPortTop + height);
HashMap<Object, FreeFlowItem> ret = new HashMap<Object, FreeFlowItem>();
for (Map.Entry<Object, FreeFlowItem> entry : mProxies.entrySet()) {
FreeFlowItem p = entry.getValue();
if (Rect.intersects(p.frame, viewport)) {
ret.put(entry.getKey(), p);
}
}
return ret;
}
@Override
public FreeFlowItem getFreeFlowItemForItem(Object item) {
return mProxies.get(item);
}
@Override
public int getContentWidth() {
if (itemsAdapter == null)
return 0;
int sectionIndex = itemsAdapter.getNumberOfSections() - 1;
Section s = itemsAdapter.getSection(sectionIndex);
if (s.getDataCount() == 0)
return 0;
Object lastFrameData = s.getDataAtIndex(s.getDataCount() - 1);
FreeFlowItem fd = mProxies.get(lastFrameData);
return fd.frame.left + fd.frame.width();
}
@Override
public int getContentHeight() {
return height;
}
@Override
public FreeFlowItem getItemAt(float x, float y) {
return ViewUtils.getItemAt(mProxies, (int) x, (int) y);
}
@Override
public boolean verticalScrollEnabled() {
return false;
}
@Override
public boolean horizontalScrollEnabled() {
return true;
}
@Override
public void setLayoutParams(FreeFlowLayoutParams params){ }
}