java linearlayout_LinearLayout的onLayout()分析

void layoutVertical() {

/**

* 1)获得子视图可用的宽度。读者可能觉得奇怪,这里是进行垂直方向上的布局,为什么却要可用

* 的宽度,而不是可用的髙度呢?因为,就算是垂直方向,子视图本身也可以水平居中,而要居中就得知

* 道可用的宽度是多少,从而计算出子视图左边沿的位置.

*/

final int paddingLeft = mPaddingLeft;

int childTop = mPaddingTop;

int childLeft;

// Where right end of child should go

final int width = mRight - mLeft;

int childRight = width - mPaddingRight;

// Space available for child

int childSpace = width - paddingLeft - mPaddingRight;

final int count = getVirtualChildCount();

final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;

final int minorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;

/**

* 根据父视图中的gravity属性,决定子视图的起始位置。在默认情况下,gravity是 TOP,应用

* 程序可以设置为BOTTOM或 者CENTER_VERTICAL,

*/

if (majorGravity != Gravity.TOP) {

switch (majorGravity) {

case Gravity.BOTTOM:

// mTotalLength contains the padding already, we add the top

// padding to compensate

childTop = mBottom - mTop + mPaddingTop - mTotalLength;

break;

case Gravity.CENTER_VERTICAL:

childTop += ((mBottom - mTop) - mTotalLength) / 2;

break;

}

}

/**

* 此时已经确定了子视图的垂直方向上的位置,于是就开始for()循环为每一个子视图分配位置。

* ( 1 ) 取 出 子 视 图 的LayoutParams,并 得 到 gravity的值。注 意 这 个 gravity值并不是子视图中

* android:gravity的值,而 是 android:layout_gravity的值,关于这一点的解释见下一小节。

* ( 2 ) 根 据 gravity的 值 确 定 水 平 方 向 上 的 起 始 位 置 , 分 为 三 种 , 分 别 是 LEFT、

* CENTER HORIZONTAL及 RIGH T

*/

for (int i = 0; i < count; i++) {

final View child = getVirtualChildAt(i);

if (child == null) {

childTop += measureNullChild(i);

} else if (child.getVisibility() != GONE) {

final int childWidth = child.getMeasuredWidth();

final int childHeight = child.getMeasuredHeight();

final LinearLayout.LayoutParams lp =

(LinearLayout.LayoutParams) child.getLayoutParams();

int gravity = lp.gravity;

if (gravity < 0) {

gravity = minorGravity;

}

switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {

case Gravity.LEFT:

childLeft = paddingLeft + lp.leftMargin;

break;

case Gravity.CENTER_HORIZONTAL:

childLeft = paddingLeft + ((childSpace - childWidth) / 2)

+ lp.leftMargin - lp.rightMargin;

break;

case Gravity.RIGHT:

childLeft = childRight - childWidth - lp.rightMargin;

break;

default:

childLeft = paddingLeft;

break;

}

/**

* 调 用 setChildFrameO,该函数内部实际上就是调用child.layout()为子视图设置布局位置。

* 至此, LinearLayout就完成了为所包含的子视图分配布局位置的过程。

*/

childTop += lp.topMargin;

setChildFrame(child, childLeft, childTop + getLocationOffset(child),

childWidth, childHeight);

childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);

i += getChildrenSkipCount(child, i);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值