关于Layout Weight,我们先来看一下官方释义。
LinearLayout通过子View的android:layout_weight属性,来为子View分配权重。layout_weight属性指定子View在屏幕上占有空间的重要性。较大的权重值使得子View可以扩充到填充父视图的任何剩余空间。子View可以指定一个weight值,然后LinearLayout根据子View声明的weight值所占的比例,来为它们分配剩余的空间。Layout Weight默认是0。
例如,如果有三个文本,其中两个声明权重为1,剩余一个没有声明权重,这个没有权重的文本,只会占据其内容所需的空间,并不会增加。而另外两个文本会同等的扩大,以填补三个文本在进行测量之后所剩余的空间。如果第三个文本声明的权重为2(而不是0),那么它的权重将比其它两个更重要,所以它会被分配一半的总剩余空间,前两个文本均分剩下的空间。
如果要创建一个线性布局,使其内部的每个子View使用屏幕上相等的空间,可以把每个子View的android:layout_height属性设置为“0dp”(对于垂直布局),或者把每个子View的android:layout_width属性设置为“0dp”(对于水平布局)。然后把每个子View的android:layout_weight属性设置为“1”。
文档读起来有点绕口,下面我们通过代码来进行验证。
(1).首先,来看看我们在开发中最常使用的方式。
布局文件:
<?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">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_blue_bright"
android:text="blog"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@android:color/holo_green_light"
android:text="csdn"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="@android:color/holo_orange_light"
android:text="net"/>
</LinearLayout>
显示效果:
三个TextView在LinearLayout中水平排列,各个控件的layout_width都是0dp,第一个控件layout_weight为1,第二个控件layout_weight为2,第三个控件layout_weight为3。显示效果如我们预期,三个控件宽度比例为1:2:3。
(2).接下来,我们重新调整第1步中三个控件的layout_width和layout_weight。此时,各个控件的layout_width都是match_parent,控件从左到右layout_weight依次是1,2,2。
布局文件:
<?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">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_blue_bright"
android:text="blog"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@android:color/holo_green_light"
android:text="csdn"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@android:color/holo_orange_light"
android:text="net"/>
</LinearLayout>
显示效果:
我们会发现,出现了跟我们预期截然不同的结果。那么为什么会出现这种情况呢,这时候我们再回到上面官方对weight的定义。
父视图根据子视图声明的weight值所占的比例,来为它们分配剩余的空间。也就是说,在这里LinearLayout先根据三个TextView的layout_width属性,为它们分配宽度,LinearLayout的宽度减去三个TextView的宽度,会有一个剩余宽度,然后LinearLayout将
剩余宽度按照三个TextView的layout_weight所占的比例来为它们分配。
这里,我们假设LinearLayout的宽度为totalWidth,每个TextView声明的宽度为childWidth(三个TextView都是match_parent,声明的宽度相等)。由于TextView的layout_width为match_parent,所以这里childWidth=totalWidth。
那么,可以计算出剩余宽度为totalWidth-childWidth*3 = -totalWidth*2。(注意:剩余空间可以为负值)
据此,我们可以计算出三个TextView的实际显示宽度。即TextView声明的宽度加上剩余宽度按weight比例分配的值。
第一个TextView的宽度:childWidth + (-totalWidth*2)*(1/5) = totalWidth*(3/5)
第二个TextView的宽度:childWidth + (-totalWidth*2)*(2/5) = totalWidth*(1/5)
第三个TextView的宽度:childWidth + (-totalWidth*2)*(2/5) = totalWidth*(1/5)
所以,这里出现了3:1:1的显示效果。
同理,我们也可以据此计算出上述第1步中1:2:3的结果。
(3).我们再来看另一种情况。将上述第2步中的三个控件的layout_width保持不变(即依旧是match_parent),layout_weight由依次是1,2,2,改为依次是1,2,3。
布局文件:
<?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">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_blue_bright"
android:text="blog"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@android:color/holo_green_light"
android:text="csdn"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="@android:color/holo_orange_light"
android:text="net"/>
</LinearLayout>
显示效果:
结果又一次出乎我们的意料,第三个控件竟然不见了。
依旧使用上述公式,计算一下我们就明朗了。
第一个TextView的宽度:childWidth + (-totalWidth*2)*(1/6) = totalWidth*(4/6)
第二个TextView的宽度:childWidth + (-totalWidth*2)*(2/6) = totalWidth*(2/6)
第三个TextView的宽度:childWidth + (-totalWidth*2)*(3/6) = totalWidth*(1/6)
虽然第三个TextView实际有父布局1/6的宽度,但是我们会发现第一个TextView和第二个TextView已经占满父控件宽度(4/6 + 2/6 = 1),所以第三个TextView被挤到屏幕之外了。
(4).还有一种情况也需要我们关注。现在LinearLayout中有两个TextView水平排列,两个TextView的layout_width都是wrap_content,layout_weight都是1,TextView均有文字内容,但文字长度不同。
直观告诉我们这两个控件一定会按照1:1的比例来显示,下面让我们看一下实际效果。
布局文件:
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_blue_bright"
android:text="http://"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_green_light"
android:text="blog.csdn.net/ruancoder"/>
</LinearLayout>
显示效果:
实际结果否定了我们的猜测,两个TextView并未均分屏幕宽度。
但是无论我们如何修改width和weight,规则是不会改变的,即TextView的宽度等于TextView声明的宽度加上剩余宽度按weight比例分配的值。
这里,TextView的宽度声明为wrap_content,也就是其内部文字的宽度,两者文字的长度是不同的,所以相当于两者声明的宽度实际为其内部文字宽度。weight值相同,说明两者会平分剩余宽度。所以,就出现了我们所看到的现象,二者并未按照1:1的比例来显示,但二者的空白区域(即非文字显示区域)却是1:1的。
那么,如何达到1:1的显示效果呢,很简单,将两个TextView的layout_width都置为0dp即可。
(5).与layout_weight相关联的,还有一个weightSum属性。layout_weight是声明在子视图的,而weightSum是声明在父视图的。实际开发中,我们可能有这种需求,在一行中只有一个控件,但却需要该控件占据一半的屏幕宽度,此时可以使用layout_weight结合weightSum实现。
布局文件:
<?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"
android:weightSum="2">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/holo_blue_bright"
android:text="blog.csdn.net"/>
</LinearLayout>
显示效果:
通过weightSum属性,可以指定LinearLayout内部所有子视图的weight总和。如果该属性未设定,则其值为内部所有子视图的weight值相加计算的总和。
这里,父视图的weightSum等于2,子视图的layout_width等于0,且layout_weight等于1,所以子视图占据了父视图一半的宽度。
总结:
线性布局在为子控件分配尺寸时,首先按照子控件声明的尺寸进行分配,然后再加上剩余尺寸按weight所占比例计算的值。
今天的文章布局属性layout_weight解析分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13257.html