What does android:layout_weight mean?
Asked Answered
L

13

691

I don't understand how to use this attribute. Can anyone tell me more about it?

Limpopo answered 22/10, 2010 at 10:10 Comment(0)
F
906

With layout_weight you can specify a size ratio between multiple views. E.g. you have a MapView and a table which should show some additional information to the map. The map should use 3/4 of the screen and table should use 1/4 of the screen. Then you will set the layout_weight of the map to 3 and the layout_weight of the table to 1.

To get it work you also have to set the height or width (depending on your orientation) to 0px.

Feltie answered 22/10, 2010 at 10:55 Comment(12)
head scratcher until you mentioned the 0px height!Leucomaine
To define which of them will be affected by weight. Width or height.Except
You do need the 0px. Example: you want to implement a table with two equally-sized columns. Each table row is a horizontal linear layout with two "table cells" (for example, TextViews), each one having layout_weight=.5. If you specify layout_width="wrap_content" on the "table cells," the content width will be added to the width calculated by layout_weight, the table cells will be all different sizes, and the columns won't line up correctly. So you have to set layout_width=0dp so that android only uses layout_weight to calculate the width of the cells.Clinic
What if the parent is a RelativeLayout, will it act on width or height, which one needs to be set to 0px?Backhand
You don't need the 0px in a child of LinearLayout because the android:orientation attribute specifies the whether the items are arranged vertically or horizontally.Dissimilitude
0px on height or width (while using layout_weight) does not work for buttons. It makes them disappear.Minne
@Solace, late answer, but for completeness sake .. Seems like weight attribute is not contributing to RelativeLayout. It only works with LinearLayout. If you see a need for weigth, perhaps the way to go is to create a LinearLayout (with weightages) within RelativeLayout.Quinnquinol
Also ..Maybe For beginners....If Layout has multiple children's ,then do not forget to give layout_weight to each and every view.Madcap
I used this inside a horizontal RadioGroup with two RadioButtons inside a RelativeLayout. Setting the first wieght to 1 and the second to 3 gave me a nice margin between the first and second.Dogmatist
if you include the layout_weight attribute then the system has to calculate the width (or height) a second time, using the weight value to allocate space. It’s twice the work. This is why you should set the width or height attribute value to 0dp so there’s no extra calculation. The system then uses the weight attribute to do the calculation.Encyclopedic
The very same explanation holds for GridLayout - if you want to stretch in both directions both of them needs the 0dp!Calceiform
For a better understanding, you can imagine the distribution in percent. Means you have e.g. 3 buttons, one of them takes half of the screen, the other two fill the second half. Then you can set the weights like this: 50, 25, 25Cockfight
C
267

In a nutshell, layout_weight specifies how much of the extra space in the layout to be allocated to the View.

LinearLayout supports assigning a weight to individual children. This attribute assigns an "importance" value to a view, and allows it to expand to fill any remaining space in the parent view. Views' default weight is zero.

Calculation to assign any remaining space between child

In general, the formula is:

space assigned to child = (child's individual weight) / (sum of weight of every child in Linear Layout)

Example 1

If there are three text boxes and two of them declare a weight of 1, while the third one is given no weight (0), then remaining space is assigned as follows:

1st text box = 1/(1+1+0)

2nd text box = 1/(1+1+0)

3rd text box = 0/(1+1+0)

Example 2

Let's say we have a text label and two text edit elements in a horizontal row. The label has no layout_weight specified, so it takes up the minimum space required to render. If the layout_weight of each of the two text edit elements is set to 1, the remaining width in the parent layout will be split equally between them (because we claim they are equally important).

Calculation:

1st label = 0/(0+1+1)

2nd text box = 1/(0+1+1)

3rd text box = 1/(0+1+1)

If, instead, the first one text box has a layout_weight of 1, and the second text box has a layout_weight of 2, then one third of the remaining space will be given to the first, and two thirds to the second (because we claim the second one is more important).

Calculation:

1st label = 0/(0+1+2)

2nd text box = 1/(0+1+2)

3rd text box = 2/(0+1+2)


Source article

Cirri answered 22/10, 2010 at 10:46 Comment(7)
A much better explanation than the currently selected answer.Purveyor
Well, there's the simple explanation (which I appreciate) and the nitty gritty details (which I appreciate in a different way). They're both good answers.Heptameter
As mentioned elsewhere, android:layout_width="0px" is important. Also, the weights don't need to be integers.Hunt
This is a bit more difficult to understand than the selected answer, but it gives the complete answer - particularly when some views have weights and some do not. That's a huge use case not covered by the selected answer.Lactate
I want to disagree that this is hard to understand. It is the reverse, he let us know why they called it WEIGHT. Because of it means importance. As in what he says carries alot of weight. I also disagree that the first answer simple and to the point. The answer still left me scratching my mind, and completing ignorant to what the attribute does. This answer is golden. I now have firm footing.Chronaxie
Adding to this answer, there is LinearLayout.android:weightSum which is handy. You can explicitly tell the compiler the total to use when calculating the remaining space.Chronaxie
For a better understanding, you can imagine the distribution in percent. Means you have e.g. 3 buttons, one of them takes half of the screen, the other two fill the second half. Then you can set the weights like this: 50, 25, 25Cockfight
S
75

adding to the other answers, the most important thing to get this to work is to set the layout width (or height) to 0px

android:layout_width="0px"

otherwise you will see garbage

Simone answered 15/8, 2012 at 7:52 Comment(1)
I think it depends if you want to hide views which don't define their weights or you want to show them with size-to-fit size and leave the remaining free space to the "weighted" views.Accommodation
K
45

If there are multiple views spanning a LinearLayout, then layout_weight gives them each a proportional size. A view with a bigger layout_weight value "weighs" more, so it gets a bigger space.

Here is an image to make things more clear.

enter image description here

Theory

The term layout weight is related to the concept of weighted average in math. It is like in a college class where homework is worth 30%, attendance is worth 10%, the midterm is worth 20%, and the final is worth 40%. Your scores for those parts, when weighted together, give you your total grade.

enter image description here

It is the same for layout weight. The Views in a horizontal LinearLayout can each take up a certain percentage of the total width. (Or a percentage of the height for a vertical LinearLayout.)

The Layout

The LinearLayout that you use will look something like this:

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

    <!-- list of subviews -->

</LinearLayout>

Note that you must use layout_width="match_parent" for the LinearLayout. If you use wrap_content, then it won't work. Also note that layout_weight does not work for the views in RelativeLayouts (see here and here for SO answers dealing with this issue).

The Views

Each view in a horizontal LinearLayout looks something like this:

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

Note that you need to use layout_width="0dp" together with layout_weight="1". Forgetting this causes many new users problems. (See this article for different results you can get by not setting the width to 0.) If your views are in a vertical LinearLayout then you would use layout_height="0dp", of course.

In the Button example above I set the weight to 1, but you can use any number. It is only the total that matters. You can see in the three rows of buttons in the first image that I posted, the numbers are all different, but since the proportions are the same, the weighted widths don't change in each row. Some people like to use decimal numbers that have a sum of 1 so that in a complex layout it is clear what the weight of each part is.

One final note. If you have lots of nested layouts that use layout_weight, it can be bad for performance.

Extra

Here is the xml layout for the top image:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

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

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

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:text="2" />

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

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

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

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:text="10" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="20" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:text="10" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

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

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".25"
            android:text=".25" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".50"
            android:text=".50" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".25"
            android:text=".25" />

    </LinearLayout>

</LinearLayout>
Kolk answered 18/4, 2015 at 6:29 Comment(1)
I always wonder why more people don't post images to accompany their XML. It's much easier to understand visuals than code.Staphylo
F
30

layout_weight tells Android how to distribute your Views in a LinearLayout. Android then first calculates the total proportion required for all Views that have a weight specified and places each View according to what fraction of the screen it has specified it needs. In the following example, Android sees that the TextViews have a layout_weight of 0 (this is the default) and the EditTexts have a layout_weight of 2 each, while the Button has a weight of 1. So Android allocates 'just enough' space to display tvUsername and tvPassword and then divides the remainder of the screen width into 5 equal parts, two of which are allocated to etUsername, two to etPassword and the last part to bLogin:

<LinearLayout android:orientation="horizontal" ...>

    <TextView android:id="@+id/tvUsername" 
    android:text="Username" 
    android:layout_width="wrap_content" ... />

    <EditText android:id="@+id/etUsername"
    android:layout_width="0dp"
    android:layout_weight="2" ... />

    <TextView android:id="@+id/tvPassword"
    android:text="Password"
    android:layout_width="wrap_content" />

    <EditText android:id="@+id/etPassword"
    android:layout_width="0dp"
    android:layout_weight="2" ... />

    <Button android:id="@+id/bLogin"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:text="Login"... />

</LinearLayout>

It looks like:
landscape orientation and
portrait orientation

Fascicule answered 23/2, 2014 at 15:42 Comment(0)
Z
16

Think it that way, will be simpler

If you have 3 buttons and their weights are 1,3,1 accordingly, it will work like table in HTML

Provide 5 portions for that line: 1 portion for button 1, 3 portion for button 2 and 1 portion for button 1

Regard,

Zucker answered 4/11, 2011 at 16:55 Comment(0)
F
10

one of the best explanations for me was this one (from the Android tutorial, look for step 7):

layout_weight is used in LinearLayouts to assign "importance" to Views within the layout. All Views have a default layout_weight of zero, meaning they take up only as much room on the screen as they need to be displayed. Assigning a value higher than zero will split up the rest of the available space in the parent View, according to the value of each View's layout_weight and its ratio to the overall layout_weight specified in the current layout for this and other View elements.

To give an example: let's say we have a text label and two text edit elements in a horizontal row. The label has no layout_weight specified, so it takes up the minimum space required to render. If the layout_weight of each of the two text edit elements is set to 1, the remaining width in the parent layout will be split equally between them (because we claim they are equally important). If the first one has a layout_weight of 1 and the second has a layout_weight of 2, then one third of the remaining space will be given to the first, and two thirds to the second (because we claim the second one is more important).

Favien answered 19/7, 2011 at 19:16 Comment(0)
B
7

http://developer.android.com/guide/topics/ui/layout-objects.html#linearlayout

layout_weight defines how much space the control must obtain respectively to other controls.

Bisayas answered 22/10, 2010 at 10:42 Comment(0)
G
7

For additional

For vertical orientation, don't forget set height to 0dp

android:layout_height="0dp"

For horizontal orientation, don't forget set width to 0dp

android:layout_width="0dp"
Gynaeco answered 24/6, 2018 at 9:45 Comment(0)
T
3

Please look at the weightSum of LinearLayout and the layout_weight of each View. android:weightSum="4" android:layout_weight="2" android:layout_weight="2" Their layout_height are both 0px, but I am not sure it is relevan

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4">

<fragment android:name="com.example.SettingFragment"
    android:id="@+id/settingFragment"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="2"
    />

<Button
    android:id="@+id/dummy_button"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="2"
    android:text="DUMMY"
    />
</LinearLayout>
Theologue answered 27/2, 2017 at 22:3 Comment(1)
Please look at the weightSum of LinearLayout and the layout_weight of each View. android:weightSum="4" android:layout_weight="2" android:layout_weight="2" Their layout_height are both 0px, but I am not sure it is relevant.Theologue
I
0

Combining both answers from

Flo & rptwsthi and roetzi,

Do remember to change your layout_width=0dp/px, else the layout_weight behaviour will act reversely with biggest number occupied the smallest space and lowest number occupied the biggest space.

Besides, some weights combination will caused some layout cannot be shown (since it over occupied the space).

Beware of this.

Internalcombustion answered 2/10, 2013 at 6:34 Comment(0)
C
0

Adding android:autoSizeTextType="uniform" will resize the text for you automatically

Canto answered 15/8, 2018 at 17:42 Comment(0)
Q
-1

As the name suggests, Layout weight specifies what amount or percentage of space a particular field or widget should occupy the screen space.
If we specify weight in horizontal orientation, then we must specify layout_width = 0px.
Similarly, If we specify weight in vertical orientation, then we must specify layout_height = 0px.

Quechua answered 9/12, 2013 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.