168

我想知道:什么是 android:weightSum 和布局权重,它们是如何工作的?

4

10 回答 10

180

加上 superM 和 Jeff 的回答,

如果LinearLayout中有2个view,第一个layout_weight为1,第二个layout_weight为2且未指定weightSum,默认计算weightSum为3(children权重之和),第一个视图占空间的 1/3,而第二个视图占 2/3。

但是,如果我们将 weightSum 指定为 5,则第一个将占用 1/5 的空间,而第二个将占用 2/5 的空间。因此,总共 3/5 的空间将被布局占用,其余部分为空。

于 2012-10-08T06:59:12.880 回答
136

根据文档,定义最大权重总和,如果未明确指定android:weightSum,则计算为所有子代的总和。layout_weight

让我们考虑一个LinearLayout带有水平方向和ImageViews内部 3 的示例。现在我们希望这些ImageViews总是占据相等的空间。为了实现这一点,您可以将layout_weight每个设置ImageView为 1,并且weightSum将计算为等于 3,如注释中所示。

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    <!-- android:weightSum="3" -->
    android:orientation="horizontal"
    android:layout_gravity="center">

   <ImageView
       android:layout_height="wrap_content"       
       android:layout_weight="1"
       android:layout_width="0dp"/>
  .....

weightSum对于为任何设备正确呈现布局很有用,如果您直接设置宽度和高度,则不会发生这种情况。

于 2011-09-17T05:59:25.827 回答
29

权重总和完全按照您的意愿工作(就像其他答案一样,您不必对父布局上的所有权重求和)。在子视图上指定您希望它承受的重量。不要忘记指定

android:layout_width="0dp" 

下面是一个例子

    <LinearLayout
                android:layout_width="500dp"
                android:layout_height="20dp" >

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="3"
                    android:background="@android:color/holo_green_light"
                    android:gravity="center"
                    android:text="30%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="2"
                    android:background="@android:color/holo_blue_bright"
                    android:gravity="center"
                    android:text="20%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="5"
                    android:background="@android:color/holo_orange_dark"
                    android:gravity="center"
                    android:text="50%"
                    android:textColor="@android:color/white" >
                </TextView>
 </LinearLayout>

这看起来像

在此处输入图像描述

于 2016-06-27T20:48:04.047 回答
25

文档说得最好,并包含一个示例(突出显示我的)。

机器人:重量总和

定义最大重量总和。如果未指定,则通过添加所有子项的 layout_weight 来计算总和。例如,这可以用于通过将 layout_weight 设置为 0.5 并将 weightSum 设置为 1.0来为单个子项提供总可用空间的 50%。

所以为了纠正 superM 的例子,假设你有一个LinearLayout包含两个ImageViews和一个with 的水平方向TextView。您将 定义TextView为具有固定大小,并且您希望两者ImageViews平等地占用剩余空间。

要做到这一点,您将layout_weight1 应用于每个ImageView,none 应用于TextView,并且weightSum2.0 应用于LinearLayout.

于 2012-10-04T03:35:21.420 回答
20

经过一些实验,我认为 LinearLayout 的算法是这样的:

假设weightSum设置为一个值。缺席的情况将在后面讨论。

首先,除以weightSum元素的数量,match_parent或者fill_parent在LinearLayout 的维度中(例如layout_widthfor orientation="horizontal")。我们将此值称为w_m每个元素的权重乘数。的默认值为weightSum1.0,因此默认权重乘数为1/n,其中nfill_parent元素个数;wrap_content元素没有贡献n

w_m = weightSum / #fill_parent

例如,当weightSum是 60,并且有 3 个fill_parent元素时,权重乘数为 20。权重乘数是例如layout_width属性不存在时的默认值。

其次,计算每个元素的最大可能扩展。首先,根据wrap_content元素的内容计算元素。它们的扩展是从父容器的扩展中扣除的。我们将调用剩余部分expansion_remainer。这个余数根据元素分布在fill_parent元素中layout_weight

第三,每个fill_parent元素的展开计算如下:

w_m - ( layout_weight / w_m ) * maximum_possible_expansion

例子:

如果weightSum是 60,并且有 3 个fill_parent元素的权重分别为 10、20 和 30,它们在屏幕上的扩展是父容器的 2/3、1/3 和 0/3。

weight | expansion
     0 | 3/3
    10 | 2/3
    20 | 1/3
    30 | 0/3
    40 | 0/3

最小扩展上限为 0。最大扩展上限为父大小,即权重上限为 0。

如果一个元素设置为wrap_content,则首先计算其展开,其余展开受fill_parent元素之间的分布影响。如果weightSum设置,这将导致对元素layout_weight没有影响。wrap_content但是,wrap_content元素仍然可以被权重小于的元素推出可见区域权重乘数(例如,在 0-1 之间,weightSum= 1 或在 0-20 之间,对于上面的示例)。

如果没有weightSum指定,它被计算为所有layout_weight值的总和,包括带有wrap_contentset!的元素。因此,layout_weight设置wrap_content元素可以影响它们的扩展。例如,负权重会缩小其他fill_parent元素。在fill_parent布局元素之前,是否将上述公式应用于wrap_content元素,最大可能的扩展是它们根据包装内容的扩展。元素将wrap_content被缩小,然后fill_parent计算和分配剩余元素的最大可能扩展。

这可能会导致不直观的结果。

于 2014-04-08T16:16:20.293 回答
10

如果未指定,则通过添加所有子项的 layout_weight 来计算总和。例如,这可以用于通过将 layout_weight 设置为 0.5 并将 weightSum 设置为 1.0 来为单个子项提供总可用空间的 50%。必须是浮点值,例如“1.2”

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main_rel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="2.0" >

        <RelativeLayout
            android:id="@+id/child_one"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#0000FF" >
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/child_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#00FF00" >
        </RelativeLayout>

    </LinearLayout>
于 2013-04-16T11:49:24.427 回答
7

似乎没有人提到的一件事:假设您有一个vertical LinearLayout,因此为了使其内部的布局/元素/视图中的权重 100% 正常工作 - 所有这些都必须具有layout_height属性(必须存在于您的 xml文件)设置为0dp. 在某些情况下,似乎任何其他值都会把事情搞砸。

于 2014-08-06T16:03:07.310 回答
2

布局权重就像一个比率。例如,如果有一个垂直布局并且有两个项目(例如按钮或文本视图),一个具有布局权重 2,另一个具有布局权重 3。然后第一项将占据屏幕/布局的 5 部分中的 2 部分,而另一部分将占据 5 部分中的 3 部分。这里5是重量总和。即权重总和将整个布局划分为定义的部分。 布局权重定义了特定项目在预定义的总权重总和中所占的比例。重量总和也可以手动声明。当使用线性布局进行 UI 设计时,按钮、文本视图、编辑文本等都使用 weightsum 和布局权重进行组织。

于 2016-05-11T15:18:47.707 回答
1

来自开发者文档

例如,这可以用于通过给它一个 layout_weight并将 weightSum 设置为来给50%总可用空间的单个孩子。0.51.0

除了@Shubhayu 答案

rest3/5可用于其他真正不需要包含布局的任何特定部分的子布局。

这是android:weightSum财产的潜在用途。

于 2016-03-29T06:35:37.050 回答
0

没有人明确提到这weightSumLinearLayout.

weightSum我相信这对像我一样一开始感到困惑并在ConstraintLayout文档中寻找的任何人都有帮助。

于 2021-01-16T17:13:01.047 回答