jaywhy13
jaywhy13

Reputation: 1116

Why does Android layout weight and wrap_content give more space than needed?

I was fooling around with Android layouts to try and get a better understanding of weights, I stumbled across a scenario I couldn't explain though. I have three UI components in a row. A LinearLayout with a weight of 1 and wrap_content for the width (it has a button inside it) followed by two buttons with 0dp width and weight of 1. I was expecting that the LinearLayout would be smaller than the width of the buttons but when it's rendered, the LinearLayout takes up half of the space and each button gets a quarter of the screen space. This happens even though the first button (inside the LinearLayout) is much smaller than the space the linear layout uses up. Can anyone explain why?

PS: I know this works fine (all equally spaced) if you give the LinearLayout a width of 0dp and weight of 1, but was wondering why this scenario resulted the way it did.

<LinearLayout
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="wrap_content">

    <LinearLayout
            android:layout_width="wrap_content"
            android:orientation="horizontal"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/holo_blue_bright">
        <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="W =  1"/>
    </LinearLayout>

    <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="W =  1"/>
    <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="W =  1"/>
</LinearLayout>          

Upvotes: 3

Views: 8371

Answers (4)

Al0x
Al0x

Reputation: 937

You need to define

android:weightSum="" // 3 in your case

in your outer LinearLayout

Upvotes: 0

krishan711
krishan711

Reputation: 873

I don't think you need to define a weightSum like others are saying.

I tested out your code, and in fact it is very interesting what you have discovered. What seems to be happening is that the inner LinearLayout first uses wrap content to gets its base width, and then shared the remaining width between itself and the two other buttons. Hence, the inner button is small (just using its bare minimum width), and the LinearLayout has a width equal to the small button + one of the other buttons.

I hope this makes sense. Nice discovery!

Upvotes: 1

codeMagic
codeMagic

Reputation: 44571

I'm not sure if I can clearly explain why this doesn't work other than if you use weight then your View should have a width or height of 0 depending on the orientation of its parent. Sorry, I am better with examples than words. However, I can tell you that to achieve what you want, simply take out the layout_weight attribute from the child LinearLayout and you will get the desired effect.

This will wrap the LinearLayout to what it needs then have the two Buttons take up the rest of the space equally. Give it a try and you will see what I mean. I think there's an article that talks about this a little. I will see if I can find it.

<LinearLayout
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:layout_height="wrap_content">

<LinearLayout
        android:layout_width="wrap_content"
        android:orientation="horizontal"
        android:layout_height="wrap_content"  // removed weight so the LL will just wrap the content
        android:background="@android:color/holo_blue_bright">

Found it

layout_weight this part of the docs has an example of what you are trying to do.

Upvotes: 1

Mohit
Mohit

Reputation: 11324

You are setting weight to LinearLayout so its taking all available space

and also you are not defining the weight_sum to any parent

 <LinearLayout
        android:layout_width="wrap_content"
            android:orientation="horizontal"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/holo_blue_bright">
        <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="W =  1"/>
    </LinearLayout>

Note:

Weight is with respect to Screen's width/height not with respect to Parents width/height so remove weight

say if you set weight_sum = "10" then the whole screen may be divided into 10 parts you can then use layout_weight as per your need

weight_sum

Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children. This can be used for instance to give a single child 50% of the total available space by giving it a layout_weight of 0.5 and setting the weightSum to 1.0.

Must be a floating point value, such as "1.2".

 <LinearLayout
        android:layout_width="wrap_content"
            android:orientation="horizontal"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_blue_bright">
        <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="W =  1"/>
    </LinearLayout>

for more follow this

and also you can refer this

Upvotes: 0

Related Questions