android:layout_weight是如何工作的?

36
当我有以下代码时,显示具有四种颜色的顶部布局的面积比底部布局的面积小得多。
根据此文档,当您增加layout_weight时,它应该会增加区域,但在代码中却减少了。
<?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>

看看我的回答是否有帮助。如果它完全回答了问题,请标记一个答案。 - Anthony Graglia
8个回答

41

我曾经遇到过同样的问题。解决方法是不要在你将权重分配给控件时使用“wrap_content”或“fill_parent”。相反,将layout_height设置为0px(当处于垂直布局中时),然后子控件将按照权重值进行比例分配。


我正在尝试使用ImageView,但是linter给了我一个错误提示:“可疑的大小:这将使视图不可见,可能是为layout_width而意图”。不过将layout_height更改为“1dp”就可以解决问题了。 - phreakhead
请查看我的下面的回答。如果您使用权重和权重总和,则不需要宽度。 - Anthony Graglia
太好了!!非常感谢。 - diyoda_

33
如果您遇到以下错误: 错误

可疑的大小:这将使视图不可见,可能是为了布局而意图 ...

请记得在父元素的 android:orientation 上设置正确的参数。

3
非常感谢你!! - Mickäel A.
2
方向部分很重要。谢谢 :) - Mudassir
1
我终于发现不仅要关注当前的Linearlayout,还要注意外部布局...如果外部设置为垂直方向,但内部布局设置为水平方向,则宽度为0dp或0px也会失败。再次感谢... - VincentBear

10

如果你在LinearLayout中使用fill_parent属性,布局将尽可能占用空间,并且所有后面定义的布局项都必须处理剩余的空间。

如果你将两个LinearLayout的高度都设置为wrap_content,那么权重应该按照文档所述正常工作。


9

8
建立在Janusz所说的基础上,如果您使用fill_parent,那么您可以设置android:layout_weight来“分割”多个布局项之间的“完整区域”。 layout_weight不会增加面积,而是向右侧增加面积,但它也是相对于父级的。如果您有一个具有layout_height=fill_parent的父级,它具有layout_weight=0,并且该父级具有一个具有相同属性的兄弟节点,则将layout_weight=1设置为其中一个子项不会影响父级。
父级和兄弟节点都将占用它们可以填充的可用区域的50%。

我遇到了同样的问题。我正在使用fill_parentandroid:layout_weight来分割一个区域。然而,我增加权重的大小,该区域就变得越来越小。我可以处理这个问题,但我想要理解背后的逻辑。自然而然,更重的权重应该导致更大的区域(就像wrap_content一样),而不是相反的情况。 - znq
原因是因为layout_weight通常与设置为wrap_content的layout_width或layout_height一起使用。试试,你会发现它会根据哪个视图具有更高的权重来增加布局大小。我理解你的观点,并认为它应该在这两种情况下都这样做,因为这很令人困惑,但我只是记住它。 - marchinram

4
当使用layout_weight时,解决方案是将layout_height设置为0px。
但为什么会观察到这种明显奇怪/相反的行为呢?
简单来说:剩余空间是负数,因此权重为4的子项接收更多的负空间,其高度缩小得更多。
详细说明:
假设您的父垂直布局的高度为100像素。
每个子项的布局高度为fill_parent(即每个子项也是100像素高)。
所有子项的总高度=2 * 100像素
剩余高度=100-(2 * 100)= -100像素(它是负数)
现在,让我们在子项之间分配这个剩余高度。第一个子项将获得最大的部分:80%(即-100 * 4 /(4 + 1))。第二个子项获得20%(即-100 * 1 /(4 + 1))
现在计算结果高度:
子项1:100 +(-80)= 20px
子项2:100 +(-20)= 80px
这里没有什么奇怪的,只有数学。只需注意剩余空间可能为负数!(或将高度明确设置为0,因为这是建议的)

1
在线性布局属性中,将布局宽度从"wrap_content"更改为"fill_parent",希望能有所帮助。

1
如果LinearLayout的方向是垂直的,则将layout_height设置为0dp。如果是水平布局,则将layout_width设置为0dp。
如果不遵循以上规则,则视图倾向于根据指定的属性占用空间,因此对齐方式与预期不符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接