您的位置:首页 > 移动开发 > Android开发

RelativeLayout与LinearLayout的性能问题

2017-04-25 22:34 260 查看
说起RelativeLayout与LinearLayout的性能方面的差异,主要在于Measure部分,在Layout与Draw部分,两者几乎没有什么太大的差别。

RelativeLayout在进行onMeasure的时候,会子View进行两次Measure,而LinearLayout只需Measure一次。

因为RelativeLayout允许两个组件在X和Y方向分别互相依赖,所以需要横向进行一次onMeasure,纵向进行一次onMeasure。而LinearLayout就不存在这种问题,因为它总是横向或者纵向的。但是,如果在LinearLayout中使用了layout_weight属性来设计View,那么同样也需要进行两次onMeasure。

下面看RelativeLayout的onMeasure方法中的详细代码:

for (int i = 0; i < count; i++) {
View child = views[i];
if (child.getVisibility() != GONE) {
LayoutParams params = (LayoutParams) child.getLayoutParams();
int[] rules = params.getRules(layoutDirection);

applyHorizontalSizeRules(params, myWidth, rules);
measureChildHorizontal(child, params, myWidth, myHeight);

if (positionChildHorizontal(child, params, myWidth, isWrapContentWidth)) {
offsetHorizontalAxis = true;
}
}
}

for (int i = 0; i < count; i++) {
final View child = views[i];
if (child.getVisibility() != GONE) {
final LayoutParams params = (LayoutParams) child.getLayoutParams();

applyVerticalSizeRules(params, myHeight, child.getBaseline());
measureChild(child, params, myWidth, myHeight);
if (positionChildVertical(child, params, myHeight, isWrapContentHeight)) {
offsetVerticalAxis = true;
}

if (isWrapContentWidth) {
if (isLayoutRtl()) {
if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {
width = Math.max(width, myWidth - params.mLeft);
} else {
width = Math.max(width, myWidth - params.mLeft - params.leftMargin);
}
} else {
if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {
width = Math.max(width, params.mRight);
} else {
width = Math.max(width, params.mRight + params.rightMargin);
}
}
}

if (isWrapContentHeight) {
if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {
height = Math.max(height, params.mBottom);
} else {
height = Math.max(height, params.mBottom + params.bottomMargin);
}
}

if (child != ignore || verticalGravity) {
left = Math.min(left, params.mLeft - params.leftMargin);
top = Math.min(top, params.mTop - params.topMargin);
}

if (child != ignore || horizontalGravity) {
right = Math.max(right, params.mRight + params.rightMargin);
bottom = Math.max(bottom, params.mBottom + params.bottomMargin);
}
}
}

可以看到,RelativeLayout中对子View进行了两次Measure,一次是measureChildHorizontal,一次是measureChild。对子View先进行一次横向measure,之后再进行一次measure。

相比之下,LinearLayout的onMeasure方法:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mOrientation == VERTICAL) {
measureVertical(widthMeasureSpec, heightMeasureSpec);
} else {
measureHorizontal(widthMeasureSpec, heightMeasureSpec);
}
}十分清爽,先判断布局方向,然后按方向对子View进行Measure。
关于这个问题,可以继续参考下面这篇文章,写的相当详细:


Android中RelativeLayout和LinearLayout性能分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息