Layout Weights – Part 1

There is an often overlooked feature of layouts which is extremely powerful and allows us to get some pretty fine-grained control of the humble LinearLayout: Layout weights. We have briefly touched on layout weights in the Intelligent Layouts article, but we’ll cover them in a little more depth here.

Let’s start with a really simple example. Suppose that we want to split the display in half vertically with the following layout:

It shouldn’t be much of a surprise when we run this to see that the first of the child layouts (with the red background) fills the display because its layout_height is set to match_parent:

First layout fills the display

First layout fills the display

We could change the layout_height to be wrap_content, but this wouldn’t do what we want either because the layouts would both collapse to 0 height because they have no children. We can achieve what we want by applying a layout_weight to both of our child layouts:

If we now run this it does what we want:

Split display

Split display

So, what’s going on here? We’re defining each of the child layouts with a layout_width of match_parent, but by setting a layout_weight (i.e. changing the value of this attribute from its default of 0) we can tell the parent layout to divide the available space between controls. In this example, we have set the two layout_weight values of the child layouts to the same value, and they will be given an equal part of the available space.

If we are dividing the parent in to equal parts, we just set the children’s layout_weights all to 1. But if we want to divide it unequally, we can do that in a number of ways. We can either use decimal fractional values which total 1, or we can use integer values:

or

Both of these will produce the same result:

Biased split

Biased split

Hang on a second. While we’re certainly seeing a two thirds split, we actually gave the red layout a higher weight than the green, so we’d expect the red to take up two thirds of the available space. Moreover, when playing with layout weights it is sometimes possible to get things working both how we would expect, and how we’ve seen here. This is a common gotcha with layout weights, and the key here is that we have instructed both of the child layouts to try and fill the parent because of the layout_height=”match_parent”, and this causes the behaviour to be the opposite of what we expect. We can reverse this behaviour by changing the child layouts to use layout_height=”wrap_content” instead:

And this now does what we would expect:

Biased split

Biased split

In the concluding part of this article we’ll look at some more tricks that we can do with layout weights, and a further gotcha.

In a break with the tradition of this site, I have not included a link to the final code. The reason for this is that all of the example code fragments in this article is are pretty standalone and we are not iterating over the code to a final target. The individual examples can easily be cut and pasted individually, if required.

A Portuguese translation of this article by Lucio Maciel can be found here.

© 2011, Mark Allison. All rights reserved. This article originally appeared on Styling Android.

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License

Creative Commons License
Layout Weights – Part 1 by Styling Android, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Terms and conditions beyond the scope of this license may be available at blog.stylingandroid.com.

13 Responses to “Layout Weights – Part 1”

  1. anakin says:

    That is a pretty weird gotcha and has baffled me before.

  2. Alceu says:

    Thanks for the post. In the snippet
    “key here is that we have instructed both of the child layouts to try and fill the parent because of the layout_height=”match_parent”, and this causes the behaviour”
    I don’t understand the logic. This is a issue or I loose something?

    • Mark Allison says:

      @Alceu to be honest, I don’t follow the logic either. But what is clear to me is that if you set all children to “wrap_content” there should be a different behaviour to setting all children to “match_parent”. I can sort of see that this is doing things in the opposite direction, so implies an opposite behaviour.

      Another way to consider things is: If I were writing a layout manager, I’m not sure if there’s an obvious way of implementing this. It isn’t obvious how things should behave in the two cases, and maybe that’s why the Android implementation is confusing – because they very problem it is solving has a confusing set of parameters.

      Anyway, since I have understood that the behaviour is different depending on your layout_width values, I’ve run in to far fewer issues with my layout weights.

  3. Francesco says:

    Thank you, I finally realized the reason of the inconsisten behavior of my layout weights! :)

  4. [...] texto é uma adaptação do original Layout Weights – Part 1 de Mark Allison, feita sob a expressa autorização do [...]

  5. abhi says:

    thanks
    It was very simple and informative.

  6. Chamika says:

    Thank you very much.

    This explained me how to use weights. Big +1 :D

  7. Tutakhail says:

    Thanks, very well explained :)

  8. Ebraheem says:

    Thanks you are extremely great

  9. Hevski says:

    Brillant, Fantastic! Great Explaination

Leave a Reply