LinearLayout源码详解,android开发流程框架

本文深入探讨Android中LinearLayout的源码,重点关注如何处理wrap_content时子视图的测量以及weight属性对空间分配的影响。通过示例解释了LinearLayout在不同情况下如何根据权重分配剩余空间,并详细阐述了高度计算的逻辑,包括match_parent和wrap_content两种情况的差异。
摘要由CSDN通过智能技术生成

if (useExcessSpace) {
// 满足这两个条件,意味着父类即LinearLayout是wrap_content,或者mode为UNSPECIFIED
// 那么此时将当前子控件的高度置为wrap_content
// 为何需要这么做,主要是因为当父类为wrap_content时,其大小实际上由子控件控制
// 我们都知道,自定义控件的时候,通常我们会指定测量模式为wrap_content时的默认大小
// 这里强制给定为wrap_content为的就是防止子控件高度为0.

// The heightMode is either UNSPECIFIED or AT_MOST, and
// this child is only laid out using excess space. Measure
// using WRAP_CONTENT so that we can find out the view’s
// optimal height. We’ll restore the original height of 0
// after measurement.
//heightMode 是 UNSPECIFIED or AT_MOST, childView 只使用剩余空间
//使用WRAP_CONTENT进行测量,以便找出视图的最佳高度。测量后恢复原来高度 0
lp.height = LayoutParams.WRAP_CONTENT;
}

// 如果当前的LinearLayout不是EXACTLY模式,且子View的weight大于0,优先会把当前LinearLayout的全部可用高度用于子View测量
// 我们在代码中也可以很清晰的看到,在getChildMeasureSpec()中,子控件需要把父控件的padding,自身的margin以及一个可调节的量三者一起测量出自身的大小。那么假如在测量某个子控件之前,weight一直都是0,那么该控件在测量时,需要考虑在本控件之前的总高度,来根据剩余控件分配自身大小。而如果有weight,那么就不考虑已经被占用的控件,因为有了weight,子控件的高度将会在后面重新赋值。

// Determine how big this child would like to be. If this or
// previous children have given a weight, then we allow it to
// use all available space (and we will shrink things later
// if needed).
//确定这个孩子想要多大。如果这个或前面的孩子给了一个权重,那么我们允许它使用所有可用的空间
//(如果需要,我们将在稍后缩小内容)。
final int usedHeight = totalWeight == 0 ? mTotalLength : 0;
measureChildBeforeLayout(child, i, widthMeasureSpec, 0,
heightMeasureSpec, usedHeight);

// 重置子控件高度,然后进行精确赋值
final int childHeight = child.getMeasuredHeight();
if (useExcessSpace) {
// Restore the original height and record how much space
// we’ve allocated to excess-only children so that we can
// match the behavior of EXACTLY measurement.
//恢复原来的高度,并记录我们分配给 excess-only children 的空间大小,以便我们能够准确地匹配测量的行为。
lp.height = 0;
consumedExcessSpace += childHeight;
}

final int totalLength = mTotalLength;
// getNextLocationOffset返回的永远是0,这里是加上子控件的margin值
mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
lp.bottomMargin + getNextLocationOffset(child));
// 如果设置了measureWithLarg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值