对于android:weight这个属性在我刚开始使用时总是搞不明白它的用途是什么,感觉很不能理解,后来经过了很多的尝试并且看了其他文章,总算是大概理解了weight的计算方式。
首先,weight属性的作用是什么呢? weight单词的意思是重量、比重、权重,我们可以通过一个简单的例子来看看weight的影响到底如何。 首先我们需要知道,当不设置weight值时,weight的默认值为0,那么我们先创建两个button,将weight属性都设为0,布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button1"
android:layout_weight="0"
/>
<Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button2"
android:layout_weight="0"
/>
</LinearLayout>
运行结果如下:
当我们将两个按钮的weight属性都设置为1时,运行结果如下:
可以看出,添加了weight属性后两个空间占满了横向的空间,而且是1:1的方式分配的,那么就说明,weight属性的效果是按照权值所占比例分配空间,那么,分配的是拿一部分的空间呢?
从上面的运行结果来看,无非就是两种情况:
1、两个button将整个横向空间按照权值划分;
2、两个button将右侧空余空间按照权值划分;
那么我们将button2的weight值设置为零,button1仍然为1,若为第一种情况,那么button1则会占据整个屏幕宽度,运行结果如下:
因此,我们可以知道weight属性的作用在于使控件按照权值分配空余空间,那么如何分配呢?
其实,对于weight值,可以通过计算的方式来算出每个空间占有的空间大小。以orientation : horizontal为例:weight是对空余位置的按照权重分配,因此,只需要确定三个之就可以:控件原本的大小、weight值、空余位置大小。假设手机宽度为X,有三个控件a,b,c,控件的宽度原本为x1,x2,x3,权重分别为w1,w2,w3。那么可以计算控件添加weight后的宽度为:
a = x1+(w1/w1+w2+w3)*(空余空间)
a = x2+(w2/w1+w2+w3)*(空余空间)
a = x3+(w3/w1+w2+w3)*(空余空间)
空余空间 = X - x1 - x2 - x3。
以下面的布局文件代码为例:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bt2"
android:text="button2"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bt3"
android:text="button3"
android:layout_weight="1"
/>
</LinearLayout>
情况1:
当三个按钮的宽度都为wrap_content时,当不加layout_weight属性时,在orientation : horizontal限制下控件为相邻排放,因此最右边就会控出一部分空余空间如下左图:当我将button3的weight属性设为1时,如上面代码所示,button3将会占据右边的空余空间,而button1和button2的宽度没有发生变化。可见,weight属性会将空余位置按权重划分并且分配,在上面的例子中button1和button2的weight值都为0,而button3的weight值为1,因此空余位置都分配给了button3。计算结果如下:
设button在wrap_content情况下的宽度为y,其他参数和上面一致。
空余空间 = X - y - y - y = X - 3y
button1 = y + 0*空余空间 = y
button2 = y + 0*空余空间 = y
button = y + (1/1)*空余空间 = y + X - 3y
情况2:
那么还有这样一种情况,当三个button中有一个是match_parent时
(在这里我发现当设置三个button的width为match_parent时,所展示出来的布局样式与三个button的位置是有一定关系的(此时与weight无关)。这里分为三种情况:1、button1为match_parent,其他的两个button为wrap_content;2、button2为match_parent,其他两个button为wrap_content;3、button3为match_parent,其他两个button为wrap_content。三种情况的效果图如下:
可见前面控件的match_parent会覆盖掉后面的控件,但不会覆盖前面的控件。)
假设button1为match_parent,那么button1的宽度为手机宽度X,其他两个button为wrap_content,宽度为y,权值分别为1,1,1,那么计算结果如下:
空余空间 = X - X - y - y = -2y;
button1 = X + (1/3) * (-2y) = X - (2/3)y
button2 = y + (1/3) * (-2y) = (1/3)y
button3 = y + (1/3) * (-2y) = (1/3)y
左图为添加weight之前,右边为添加weight之后。
情况3:两个match_parent,一个wrap_content
有两个button的宽度为X,使用上面定义的变量,weight值分别为1,1,1,计算结果如下:
空余空间 = X - X - X - y = -X - y
button1 = X + (1/3) * (-X - y) = (2/3)X - (1/3)y;
button2 = X + (1/3) * (-X - y) = (2/3)X - (1/3)y;
button3 = y + (1/3) * (-X - y) = (2/3)y - (1/3)X;
左图为添加weight前,右图为添加weight后:
通过运行结果可以看出,button3没有显示,而button由于我没有设置gravity参数,因此可以看出button2有一部分在手机中没有显示,被挤出了屏幕,那就说明:
(2/3)y - (1/3)X <=0;
(2/3)X - (1/3)y + (2/3)X - (1/3)y = (4/3)X - (2/3)y > X
情况四:三个match_parent
这种情况下,设置三个全值为1,1,1,那么计算结果如下:
空余空间 = X - X - X - X = -2X
button1 = X + (1/3) * (-2X) = (1/3)X
button2 = X + (1/3)*(-2X) = (1/3)X
button3 = X + (1/3)*(-2X) = (1/3)X
展现出来的效果就是平分整个空间。