各ViewGroup性能对比

Measure: 系统对view tree执行递归(top-down traversal 深度遍历)来确定每个ViewGroup and View元素的大小, ViewGroup的Measure也会测量它的子view. 耗时最多.

Layout: 另一次递归, 父级别的ViewGroup来布局子view. 耗时较少

Draw: 第三次递归, 对每一个view tree的对象, 创建Canvas对象并发出包含view大小和位置的GPU绘制指令. 较耗时.





Relativelayout


----、


LinearLayout


--

ConstraintLayoutonMeasure

1.protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

2.        ......

3.        //四次循环计算Hierarchy

4.        if (this.mDirtyHierarchy) {

5.            this.mDirtyHierarchy = false;

6.            this.updateHierarchy();

7.            runAnalyzer = true;

8.        }

9.       

10.        ......

11.        //第一次测量子view, 包含一次循环

12.        this.internalMeasureChildren(widthMeasureSpec, heightMeasureSpec);

13.       

14.        //更新相对位置, 一次循环

15.        this.updatePostMeasures();

16.        //取决于是否使用group, 若使用有一次循环

17.        if (this.getChildCount() > 0 && runAnalyzer) {

18.            Analyzer.determineGroups(this.mLayoutWidget);

19.        }

20.        ......

21.       

22.        //对独立无依赖的view进行一次循环measure

23.        if (sizeDependentWidgetsCount > 0) {

24.            for(i = 0; i < sizeDependentWidgetsCount; ++i) {

25.                child.measure(widthSpec, heightSpec);

26.            }

27.            ......

28.        }

29.       

30.        //对独立view判断长宽如果不一致, 再进行一次measure

31.        for(i = 0; i < sizeDependentWidgetsCount; ++i) {

32.            child = (View)widget.getCompanionWidget();

33.            if (child != null && (child.getMeasuredWidth() != widget.getWidth() || child.getMeasuredHeight() != widget.getHeight()) && widget.getVisibility() != 8) {

34.                child.measure(widthSpec, widthSpec);

35.            }

36.        }

37.    }

1.

39.    private void updateHierarchy() {

40.        int count = this.getChildCount();

41.        boolean recompute = false;

1.

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

44.            View child = this.getChildAt(i);

45.            if (child.isLayoutRequested()) {

46.                recompute = true;

47.                break;

48.            }

49.        }

1.

51.        if (recompute) {

52.            this.mVariableDimensionsWidgets.clear();

53.            this.setChildrenConstraints();

54.        }

55.    }

56.   

57.    //计算子view的相互依赖关系

58.    private void setChildrenConstraints() {

59.        for(helperCount = 0; helperCount < count; ++helperCount) {

60.            child = this.getChildAt(helperCount);

61.            ConstraintWidget widget = this.getViewWidget(child);

62.            if (widget != null) {

63.                widget.reset();

64.            }

65.        }

66.       

67.        for(i = 0; i < count; ++i) {

68.            child = this.getChildAt(i);

69.            if (child instanceof Placeholder) {

70.                ((Placeholder)child).updatePreLayout(this);

71.            }

72.        }

1.

74.        for(i = 0; i < count; ++i) {

75.            child = this.getChildAt(i);

76.            ConstraintWidget widget = this.getViewWidget(child);

77.            ......

78.        }

79.    }

1.

81.    private void internalMeasureChildren(int parentWidthSpec, int parentHeightSpec) {

82.        int widgetsCount = this.getChildCount();

83.        for(int i = 0; i < widgetsCount; ++i) {

84.            ......

85.            baseline = getChildMeasureSpec(parentWidthSpec, widthPadding, width);

86.            ......

87.            childHeightMeasureSpec = getChildMeasureSpec(parentHeightSpec, heightPadding, height);

88.            child.measure(baseline, childHeightMeasureSpec);

89.        }

90.    }

91.   

92.    private void updatePostMeasures() {

93.        int widgetsCount = this.getChildCount();

94.        int helperCount;

95.       

96.        for(helperCount = 0; helperCount < widgetsCount; ++helperCount) {

97.            View child = this.getChildAt(helperCount);

98.            if (child instanceof Placeholder) {

99.                ((Placeholder)child).updatePostMeasure(this);

100.            }

101.        }

102.        ......

103.    }

很多for循环计算, 导致一次onMeasure代价较高. 但详细的条件约束, 当层次复杂时, 减少子view的遍历测量.

----



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335