概述
从第一次接触 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 内核剖析》 柯元旦 (这本书很好)。
最后
以上就是迷人马里奥为你收集整理的LinearLayout 中的 weight 属性的全部内容,希望文章能够帮你解决LinearLayout 中的 weight 属性所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复