layout_weight in android layout file

174 views Asked by At

I have this layout file from Chapter 13 of Android Programming: The Big Nerd Ranch Guide:

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

    <ImageView
        android:src="@drawable/armstrong_on_moon"
        android:contentDescription="@string/hellomoon_description"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerInside"
        android:layout_weight="1"/>

    <TableRow
        android:gravity="center|bottom"
        android:layout_weight="0">

        <Button
            android:id="@+id/hellomoon_playButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hellomoon_play"/>

        <Button
            android:id="@+id/hellomoon_stopButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hellomoon_stop"/>

    </TableRow>

</TableLayout>

And it results in a layout that looks like this. What I do not understand is how the TableRow shows up in the layout at all since its layout_weight is 0 and the ImageView's layout_weight is 1. My understanding is that the way layout_weight works is it will first respect the layout_width and layout_height of each element, and then divide up the remaning space between the elements based on layout_weight. But since the ImageView has match_parent for both its layout_width and layout_height, shouldn't it take up the whole screen and then leave nothing left to divide with the TableRow? I believe that the TableRow also has match_parent for both its layout_width and layout_height attributes since it inherited them from TableLayout, but since it came second I thought the ImageView would dominate the screen. Also, even if the the ImageView shouldn't take up the whole screen, aren't the layout_weights saying that the ImageView should get 100% of the remaining space and the TableRow should get 0%? Additionally, when I increase the layout_weight of the TableRow, the TableRow just gets pushed further and further off the screen as it increases more-- but I thought that this should increase the space the TableRow takes up on the screen. Can anyone explain what I'm misunderstanding here.

In case it helps, my understanding for layout_weight comes from this example in the book:

**How android:layout_weight works**
...

LinearLayout makes two passes to set the width of a view. In the first pass, LinearLayout looks at layout_width (or layout_height, for vertical orientation). The value for layout_width for both the Button and CheckBox is now wrap_content, so each view will get only enough space to draw itself (Figure 8.12).

...

In the next pass, LinearLayout allocates any extra space based on the values for layout_weight.
1

There are 1 answers

0
Karakuri On

The TableRow has a height of wrap_content. This is enforced by the TableLayout, as per the documentation:

The children of a TableLayout cannot specify the layout_width attribute. Width is always MATCH_PARENT. However, the layout_height attribute can be defined by a child; default value is WRAP_CONTENT. If the child is a TableRow, then the height is always WRAP_CONTENT.

TableLayout and TableRow are both LinearLayout subclasses, but I experienced the same strange behaviors when I created a layout like the one in your post. Browsing the source of TableLayout and TableRow, it's not immediately clear to me what causes this (clearly there's some overridden logic in the measuring code, but that's not really satisfactory to figure out things like column spans and to adjust column widths and such, but I'd have to dig more to figure out what's going on).

Unless this example actually needs/uses some of the special behaviors of TableLayout and TableRow, I would advise just using LinearLayouts instead for the sake of clarity. The presence of layout_weight with those two views is frankly confusing and clearly doesn't behave as expected. In either case, you don't even need the layout_weight="0", whether you use twoLinearLayout`s or keep the example as-is.