Reputation: 944
I have two linear layouts that have the same width - one with two children and one with three. I'm trying to make the last two children the same width but I can't wrap my head around why Android behaves this way. I finally got it to look the way I want it to with the following weights:
Can anyone explain to me why this is working out this way?
I tried to do some simple math to figure out why. I'm guessing it's the sum of weights, minus the weight of the child, divided by the sum of weights, times the width of the parent. So:
sum = 1 + 6
((sum - 6) / sum) * W = 14.3% * W
I tried the same algorithm for the second row but it was totally off:
sum = 1 + 1 + 1.5
((sum - 1.5) / sum) * W = 57.1% * W
The above is true only when the child widths are set to match_parent. Setting width to 0, or 0dp, actually behaves as expected - greater weights lead to more space allocated for the child. The algorithm makes a little more sense now and works as expected for both rows.
sum = 1 + 6
(1 / sum) * W = 14.3% * W
Is the former behavior for weights with child widths set to match_parent by design? If so, what is the approximate algorithm for calculating the width of the children?
Upvotes: 1
Views: 928
Reputation: 5593
According to your picture - weights are incorrect. E.g first "row": you have set first TextView with weight '1' and second weight is '6' - this means that second TextView will have more space - 6/7 of all layout width and first TextView have only 1/7. To simplify calculations imagine total width as 100(%) and divide them between views according to proportions which you want to give them.
Upvotes: -1
Reputation: 12596
First: Based on the look of your layout, it looks like you'd want to use a GridLayout instead of two LinearLayouts.
Back to your question: Don't set our layout_width to wrap_content (and especially not match_parent!) in your case. Set the layout_width to 0dp and let the layout_weight attribute distribute the available horzontal space.
The layout_weight attribute distributes/adds additional space to the specified layout_width (or layout_height for vertical oriented LinearLayouts). If you want only the layout_weight to contribute to the spacing, set layout_width to 0dp (layout_height to 0dp in case of vertically oriented LinearLayout).
Try this first and see if this behaves more to what you'd like and expect.
Try this example (where the grids are ratio 3:3:1):
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="6"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
Upvotes: 1
Reputation: 20934
You can specify weightSum
attribute for your LinearLayout
in XML to let's say 1
for your first layout. Then your first 2 TextViews
would get approx 0.9 and 0.1 weights (like 90% and 10%)
The same thing needs to be applied to the second LinearLayout
. Something like:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".9"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:weightSum="1"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight=".45"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".45"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
BTW, don't forget to set your width
attributes to 0dip
Upvotes: 1