I have this scenario:
A horizontal LinearLayout that fills the container and weightSum=100
, and two views inside with weight of 50 each.
Now how do I make t
Now how do I make these two views square (e.g. the height must be equal to their width).
If you have just those two views in the LinearLayout
you have two options:
Don't set your layout file directly as the content view, instead inflate it so you have a reference to the root from that file. Then post a Runnable
on that root view, calculate the desired height and set it back to each of the two children of the LinearLayout
that wraps them:
final View v = getLayoutInflater().inflate(
R.layout.views_specialheight, null);
v.post(new Runnable() {
@Override
public void run() {
setupHeight((ViewGroup) v);
}
});
setContentView(v);
where setupHeight()
is the method:
private void setupHeight(ViewGroup vg) {
int count = vg.getChildCount();
for (int i = 0; i < count; i++) {
final View v = vg.getChildAt(i);
if (v instanceof LinearLayout) {
int width = v.getWidth();
LinearLayout.LayoutParams lp;
View one = ((LinearLayout) v).getChildAt(0);
lp = (LinearLayout.LayoutParams) one.getLayoutParams();
lp.height = width / 2;
one.setLayoutParams(lp);
View two = ((LinearLayout) v).getChildAt(1);
lp = (LinearLayout.LayoutParams) two.getLayoutParams();
lp.height = width / 2;
two.setLayoutParams(lp);
}
}
}
This method will work pretty well if you just have a wrapper ViewGroup
subclass that wraps those LinearLayout
rows. It can(and should) be improved, but I'm sure you get the point.
The second option is to use a custom ViewGroup
(this may be used depending on what you were planing to do with the LinearLayout
) instead of the LinearLayout
like this:
The SpecialHeightViewGroup
is a class like this:
class SpecialHeightViewGroup extends ViewGroup {
public SpecialHeightViewGroup(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public SpecialHeightViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SpecialHeightViewGroup(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY
|| widthMode == MeasureSpec.AT_MOST) {
measureChildren(MeasureSpec.makeMeasureSpec(widthSize / 2,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
widthSize / 2, MeasureSpec.EXACTLY));
measureChildren(MeasureSpec.makeMeasureSpec(widthSize / 2,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
widthSize / 2, MeasureSpec.EXACTLY));
setMeasuredDimension(widthSize, widthSize / 2);
} else {
widthSize = 800; // we don't have restrictions, make it as big as we want
measureChildren(MeasureSpec.makeMeasureSpec(widthSize / 2,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
widthSize / 2, MeasureSpec.EXACTLY));
measureChildren(MeasureSpec.makeMeasureSpec(widthSize / 2,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
widthSize / 2, MeasureSpec.EXACTLY));
setMeasuredDimension(widthSize, 400);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
View one = getChildAt(0);
one.layout(0, 0, getWidth() / 2, getHeight());
View two = getChildAt(1);
two.layout(getWidth() / 2, 0, getWidth(), getHeight());
}
}
The custom class isn't properly tested so it may have bugs(it's just an example).
Offtopic: Are you trying by any chance to create an UI like on the new Windows phones(with the tiles thing)?