LinearLayout 中的 weight 属性

本文详细解析了Android中LinearLayout的weight属性工作原理及其分配机制。通过具体条件说明哪些子视图可以参与剩余空间的分配,并引用源码片段辅助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从第一次接触 weight 以来,一直是一知半解。今天重新看布局,再次遇到这个问题,查了资料,记载一下。


android:weight 是线性布局(LinearLayout)特有的属性,缺省值为零。

它的一个基本算法是:LinearLayout 剩余的空间由所有 weight 值不为零的子视图按比例分配。

但是有时候,有weight值的子视图分不到空间,不显示,因为 LinearLayout 没有剩余空间。


具体的分配方法与 LinearLayout 的 measure 过程有关。以 LinearLayout 的 orientation 属性为 vertical 为例说明。

LinearLayout 的 measure 过程的第一步是计算所有子视图的需要占用的高度。这个过程会暂时避开一部分子视图,也就是在该过程中,不计算这些子视图的高度。哪些子视图

呢? weight 大于0的子视图,没错,但是只有这一个条件是不够的,必须同时满足三个条件的子视图才会被避开。

这三个条件是: 

1.  该 LinearLayout 的高度模式为 MeasureSpec.EXACTLY, 也就是 android:layout_height 被设置为 match_parent 或者是一个确定的数值(如100dp)。

2.  该子视图的高度设置为0dp。即 android:layout_height="0dp" 。

3.  该子视图的 weight 值大于0。


满足这三个条件的子视图在第一个过程中被避开,它们在等着分配剩余的高度,也就是整个 LinearLayout 所提供的高度,除去其他子视图的总体高度后,剩余的高度。此时就有一种可能,那就是没有剩余。如果这种悲剧发生了,那它们就只能作出牺牲,不被显示在屏幕上。

另外,有些子视图的 weight 值大于0,但是没有同时满足以上三个条件,它们会被计算在内。如果最终还是有剩余空间的话,他们的 weight 值依然有效,在按比例分配剩余空间的时候,会将他们计算在内。


引用一句话: " weight 就像 股权,当有剩余时,才能 分红"。


贴一段源码: 

if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
                // Optimization: don't bother measuring children who are going to use
                // leftover space. These views will get measured again down below if
                // there is any leftover space.
                final int totalLength = mTotalLength;
                mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
            } else {
                int oldHeight = Integer.MIN_VALUE;

                if (lp.height == 0 && lp.weight > 0) {
                    // heightMode is either UNSPECIFIED or AT_MOST, and this
                    // child wanted to stretch to fill available space.
                    // Translate that to WRAP_CONTENT so that it does not end up
                    // with a height of 0
                    oldHeight = 0;
                    lp.height = LayoutParams.WRAP_CONTENT;
                }



参考资料: 《Android 内核剖析》 柯元旦 (这本书很好)。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值