Measure: 系统对view tree执行递归(top-down traversal 深度遍历)来确定每个ViewGroup and View元素的大小, ViewGroup的Measure也会测量它的子view. 耗时最多.
Layout: 另一次递归, 父级别的ViewGroup来布局子view. 耗时较少
Draw: 第三次递归, 对每一个view tree的对象, 创建Canvas对象并发出包含view大小和位置的GPU绘制指令. 较耗时.
----、
--
ConstraintLayout的onMeasure
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的遍历测量.
----