it-swarm.cn

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

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

144
Dhiral Pandya

根据文档,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对于为任何设备正确呈现布局非常有用,如果直接设置宽度和高度,则不会发生这种情况。

111
superM

加上superM和Jeff的回答,

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

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

165
Shubhayu

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

安卓:weightSum

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

因此,为了更正superM的示例,假设您有一个LinearLayoutname__,其水平方向包含两个ImageViewsname__和一个TextViewname__。您将TextViewname__定义为具有固定大小,并且您希望两个ImageViewsname__平均占用剩余空间。

要实现此目的,您可以将layout_weight 1应用于ImageViewname__,TextViewname__上为none,weightSumname__上的LinearLayoutname__为2.0。

23
Jeff Axelrod

权重和完全按照您的意愿工作(就像其他答案一样,您不必总计父布局上的所有权重)。在子视图上指定您想要的重量。 别忘了指定

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>

这看起来像

enter image description here

22
asok Buzz

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

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

首先,将weightSum除以LinearLayout维度中match_parentfill_parent的元素数(例如layout_widthorientation="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元素根据其内容计算。它们的扩展是从父容器的扩展中扣除的。我们将调用remainer 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_weightwrap_content元素没有影响。但是,wrap_content元素仍然可以被权重低于的元素推出可见区域 weight multiplier (例如,对于weightSum = 1,在0-1之间,或者对于上述示例,在0-20之间)。

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

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

19
Jens Jensen

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

有一件事似乎没有人提到过:假设你有一个 vertical LinearLayout,所以为了使布局/元素/视图中的权重100%正确地工作 - 所有这些都必须有layout_heightproperty(必须存在于xml文件中)设置为0dp。在某些情况下,似乎任何其他值都会搞砸。

6
Yoav Feuerstein

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

1
Sami Al-Jabar

来自开发人员 文档

例如,这可以通过给出50%的layout_weight并将weightSum设置为0.5来为单个子1.0提供总可用空间。

除了@Shubhayu的回答

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

这是Android:weightSum属性的潜在用途。

1
DjP