Android中的android:weightSum是什么,它是如何工作的?

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

根据文档, android:weightSum定义了最大权重和,并且如果没有明确指定,则按照所有子项的layout_weight的总和计算。

让我们考虑一个具有水平方向的LinearLayout和3个ImageViews的例子。 现在我们希望这些ImageViews始终占用相同的空间。 为了达到这个目的,你可以将每个ImageViewlayout_weight设置为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对于为任何设备正确显示布局非常有用,如果您直接设置宽度和高度,则不会发生这种情况。

加上superM和Jeff的回答,

如果LinearLayout中有两个视图,第一个layout_weight为1,第二个视图的layout_weight为2,没有weightSum,默认情况下,weightSum的计算结果为3(孩子的权重之和)和第一个视图占用1/3的空间,而第二个占2/3。

但是,如果我们将weightSum指定为5,则第一个将占据1/5的空间,而第二个将占2/5。 所以总共有3/5的空间被布局占据,其余的空闲。

文档说得最好,包括一个例子,(突出我的)。

机器人:weightSum

定义最大权重和。 如果未指定,则通过添加所有孩子的layout_weight来计算总和。 例如,通过给它一个layout_weight为0.5,并将weightSum设置为1.0的方法,可以给单个孩子50%的可用空间。

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

要做到这一点,你可以在每个ImageView上应用layout_weight 1,在TextView上应用none,在LinearLayout上应用2.0的weightSum

经过一番尝试,我认为LinearLayout的algorithm是这样的:

假设weightSum被设置为一个值。 稍后讨论缺席的情况。

首先,将weightSum除以LinearLayout的维数中的match_parentfill_parent元素的数量(例如layout_width for orientation="horizontal" )。 我们将这个值称为权重乘数 w_m 为每个元素。 weightSum的默认值是1.0,所以默认权重乘数是1/n ,其中nfill_parent元素的数量; wrap_content元素不参与n

w_m = weightSum / #fill_parent

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

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

第三,每个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_weightwrap_content元素没有影响。 然而, wrap_content元素仍然可以被重量低于的元素推出可见区域 重量乘数 (例如在0-1之间,对于上面的例子, weightSum = 1或0-20之间)。

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

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

权重总和就像你想要的一样工作(就像其他的答案,你不必总结父母布局的所有权重)。 在子视图上指定你想要的重量。 不要忘记指定

 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> 

这看起来像

在这里输入图像描述

如果未指定,则通过添加所有孩子的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> 

有一件事看起来像没有人提到过:假设你有一个垂直的 LinearLayout ,所以为了使layout / layout / view中的权LinearLayout 100%的范围内正常工作 – 它们都必须有layout_height属性(它必须存在于你的xml文件)设置为0dp 。 似乎任何其他价值会在一些情况下搞砸了。

从开发者文档

例如,通过给它一个layout_weight为0.5 ,并将weightSum设置为1.0方法,可以给单个孩子50%的可用空间。

除了@Shubhayu的回答

其余的3/5可以用于其他的子布局,这些子布局其实并不需要包含布局的任何特定部分。

这是潜在的使用android:weightSum属性。

布局权重就像一个比例。 例如,如果存在垂直布局并且存在两个项目(例如button或文字查看),则布局权重为2,另一个布局权重为3。 然后第一个项目将占据屏幕/布局的五部分中的两个,而另一个则占据五部分中的三个。 这里是5的重量总和。 即权重总和将整个布局划分为定义的部分。 布局权重定义了特定项目在预先定义的总权重总和中所占的比例。 重量总和也可以手动声明。 在UIdevise中使用线性布局时,button,文字浏览,编辑文本等都是使用权重和布局权重来组织的。