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:
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:
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:
Both of these will produce the same result:
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:
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.
Copyright © 2011 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.