36

When I have the following, it shows top layout with four colors has much smaller area than the bottom layout area.

According to this documentation, when you add more to layout_weight, it should increase the area, but it decreases in the code.

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

  <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:layout_weight="4">
      <TextView
          android:text="red"
          android:gravity="center_horizontal"
          android:background="#aa0000"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="3"/>
      <TextView
          android:text="green"
          android:gravity="center_horizontal"
          android:background="#00aa00"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
      <TextView
          android:text="blue"
          android:gravity="center_horizontal"
          android:background="#0000aa"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
      <TextView
          android:text="yellow"
          android:gravity="center_horizontal"
          android:background="#aaaa00"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
  </LinearLayout>

  <LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1">
    <TextView
        android:text="row one"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="row two"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="row three"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="row four"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
  </LinearLayout>

</LinearLayout>
halfer
  • 19,824
  • 17
  • 99
  • 186
shin
  • 31,901
  • 69
  • 184
  • 271

8 Answers8

41

I had the same problem. The trick is not to use "wrap_content" or "fill_parent" for the controls you are setting a weight to. Instead set the layout_height to 0px (when inside a vertical layout) and then the child controls will get proportioned per the weight values.

kbriggs
  • 1,267
  • 1
  • 12
  • 16
  • I'm trying this with an ImageView and the linter is giving me an error: "Suspicious size: this will make the view invisible, probably intended for layout_width". Changing the layout_height to "1dp" worked though. – phreakhead May 09 '13 at 17:45
  • Check out my answer below. You should not need width if you use weight and weight sum. – Anthony Graglia Aug 15 '13 at 09:37
33

If you get the error as

error

Suspicious size: this will make the view invisible, probably intended for layout ...

remember to set the correct parameter on android:orientation in parent

Ajay2707
  • 5,690
  • 6
  • 40
  • 58
pedroca
  • 1,748
  • 1
  • 19
  • 17
  • 2
    Orientation part is important. Thanks :) – Mudassir Jan 06 '15 at 14:37
  • 1
    I finally found it's not only pay attention on the current Linearlayout , but also care of the outter layout... If the outter set orientation is Vertical, but inner layout set correct as horizontal, the width with 0dp or 0px are also failure,,, Thanks again... – VincentBear May 22 '15 at 10:18
10

If you are using fill_parent in a LinearLayout the layout will take as much space as possible and all layout items defined later will have to deal with the space left.

If you set the height of both of you LinearLayouts to wrap_content the weight should work as documented.

Janusz
  • 187,060
  • 113
  • 301
  • 369
9

I know this is late but hopefully it helps people:

Use android:weightSum on the parent. Here is a link to the dev docs.

http://developer.android.com/reference/android/widget/LinearLayout.html#attr_android:weightSum

Use android:weightSum of 1.0 on the parent and then use 0.x on the child views with android:layout_weight in order for them to use that ratio of space.

Anthony Graglia
  • 5,355
  • 5
  • 46
  • 75
8

Building on what Janusz said, if you use fill_parent, you can then set android:layout_weight to "split" the "full area" between multiple layout items.

The layout_weight doesn't increase the area, it increases it "right" to the area. but it's also relative to the parent. If you have a parent with a layout_height=fill_parent, with a layout_weight=0 and the parent has a sibling with the same, setting layout_weight=1 to one of the children does not affect the parent.

Both the parent, and the sibling, would take up 50% of the available area that they can fill.

Ryan Conrad
  • 6,870
  • 2
  • 36
  • 36
  • I'm having the same issue. I'm using `fill_parent` and `android:layout_weight` to split up an area. However, the bigger I make the weight, the smaller the area gets. I can work with that, but I would like to understand the logic behind it. Naturally heavier weight should result in a larger area (as it does with `wrap_conent`) and not the other way around. – znq Sep 02 '10 at 14:23
  • The reason is because layout_weight is normally used with layout_width or layout_height set to wrap_content. Try it, you'll see that it then increases the layout sized based on which view has the higher weight. I understand your point and think it should do this for both instances because it is confusing, but I just remember it. – marchinram Oct 24 '10 at 11:00
4

The solution is to set layout_height to 0px when you use layout_weight.

But why do you observe this apparently strange/inversed behavior ?

Shortly : the remaining space is negative and so the child with weight 4 receive more negative space and it's height is more reduced.

Details :

Assume that the height of your parent vertical layout is 100 pixels.

Layout height on each child is fill_parent (i.e. each child is also 100 pixels height)

The total height of all child = 2*100 pixels

The remaining height = 100 - (2*100) = -100 pixels (it is negative)

Now, let's distribute this remaining height between child. The first one will receive the biggest part : 80% (i.e. -100*4/(4+1)). The second child receive 20% (i.e. -100*1/(4+1))

Now compute the resulting height :

child 1 : 100 + (-80) = 20px

child 2 : 100 + (-20) = 80px

Nothing strange here, only mathematics. Just be aware that remaining space can be negative ! (or set the height explicitly at 0 as it is recommended)

ben75
  • 29,217
  • 10
  • 88
  • 134
1

If the orientation of linearlayout is vertical,then set layout_height as 0dp. In case of horizontal layout set layout_width as 0dp.

If we do not follow above rules,the view tends to take up space as per specified attributes and hence the alignment is not as per expectation.

Shinoo Goyal
  • 601
  • 8
  • 10
1

In linear layout properties change the layout width to "fill_parent" instead of "wrap_content" hope it helps.

Andro Selva
  • 53,910
  • 52
  • 193
  • 240
logeshps
  • 21
  • 2