I've made a very simple ViewGroup subclass, "QuadLayout", which is intended to divide the view's space into equal quarters, and lay the children out appropriately.
Note, this layout is "dumb" - it doesn't attempt to calculate children's preferred heights or widths, no gravity, etc. It just sets four children into top-left, top-right, bottom-left, & bottom-right quadrants. The only reason I wrote this layout is because TableLayout & GridLayout refuse to give me even row heights. They seem to defer to children height preferences, and instead of an even row height, I get one short row and one tall row.
Now, the children I'm laying out are CardView subclasses, and they inflate a layout with a few TextViews and an ImageView. Very simple layout for each card.
Here's the problem.
When I use TableLayout or GridLayout (with the aforementioned row sizing issues) the card's contents are rendered.
When I use my QuadLayout, the cards are correctly laid out, but the card's TextViews, and ImageViews are not visible. I've stepped through with the debugger and confirmed the card's layout is being inflated, and the TextViews and ImageViews are being found and are not-null. And the appropriate model data is being assigned.
I've overridden onLayout in my CardView subclass, and I've confirmed that while the CardView itself is assigned correct layout (left,top,right,bottom) its children do not get laid out! They all have left/right/top/bottom of 0!
public class QuadLayout extends ViewGroup {
private static final String TAG = "QuadLayout";
private Rect childRect = new Rect();
public QuadLayout(Context context) {
super(context);
setWillNotDraw(true);
}
public QuadLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
setWillNotDraw(true);
}
public QuadLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setWillNotDraw(true);
}
@Override
public boolean shouldDelayChildPressedState() {
// we don't scroll children
return false;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
//Log.d(TAG, "onMeasure width: " + width + " height: " + height);
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int innerLeft = this.getPaddingLeft();
int innerTop = this.getPaddingTop();
int innerRight = this.getMeasuredWidth() - this.getPaddingRight();
int innerBottom = this.getMeasuredHeight() - this.getPaddingBottom();
int innerWidth = innerRight - innerLeft;
int innerHeight = innerBottom - innerTop;
int horizontalCenter = innerLeft + (int) (Math.ceil(innerWidth / 2f));
int verticalCenter = innerTop + (int) (Math.ceil(innerHeight / 2f));
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
switch (i) {
case 0: {
childRect.left = innerLeft;
childRect.top = innerTop;
childRect.right = horizontalCenter;
childRect.bottom = verticalCenter;
break;
}
case 1: {
childRect.left = horizontalCenter;
childRect.top = innerTop;
childRect.right = innerRight;
childRect.bottom = verticalCenter;
break;
}
case 2: {
childRect.left = innerLeft;
childRect.top = verticalCenter;
childRect.right = horizontalCenter;
childRect.bottom = innerBottom;
break;
}
case 3: {
childRect.left = horizontalCenter;
childRect.top = verticalCenter;
childRect.right = innerRight;
childRect.bottom = innerBottom;
break;
}
default:
throw new IllegalStateException("QuadLayout only supports a max of 4 children");
}
LayoutParams lp = (LayoutParams) child.getLayoutParams();
childRect.left += lp.leftMargin;
childRect.top += lp.topMargin;
childRect.right -= lp.rightMargin;
childRect.bottom -= lp.bottomMargin;
child.layout(childRect.left, childRect.top, childRect.right, childRect.bottom);
}
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
public static class LayoutParams extends MarginLayoutParams {
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
}
Thanks in advance,
Aucun commentaire:
Enregistrer un commentaire