RelativeLayout与LinearLayout的性能问题

来源:互联网 发布:办公室软件2013下载 编辑:程序博客网 时间:2024/06/06 01:12

说起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性能分析



0 0
原创粉丝点击