在 Android 中,UI 绘制的过程涉及到三个关键步骤:Measure(测量)、Layout(布局)和Draw(绘制),这些步骤协同工作以完成视图的最终显示。
1. Measure(测量)
测量阶段是确定每个视图(View)的大小(宽度和高度)的过程。
-
触发时机:
- 当一个视图被添加到视图层次结构中时,或者当视图的大小发生变化时(如窗口大小变化、布局变化等),测量过程会被触发。
-
调用顺序:
- 系统会自顶向下遍历视图树,调用每个视图的
measure()
方法。 - 在
measure()
方法中,视图会根据父容器传递的测量要求(MeasureSpec),计算出自身的尺寸大小。
- 系统会自顶向下遍历视图树,调用每个视图的
-
MeasureSpec:
- 在测量过程中,每个视图会根据父容器传递的
MeasureSpec
来计算自身的大小。 MeasureSpec
包含了两部分信息:大小(Size)和测量模式(Mode)。- 测量模式包括三种类型:UNSPECIFIED、EXACTLY 和 AT_MOST,分别表示未指定模式、精确模式和最大模式。
- 在测量过程中,每个视图会根据父容器传递的
2. Layout(布局)
布局阶段是确定每个视图在父容器中的位置(左上角的坐标)和大小的过程。
-
触发时机:
- 当视图的大小发生变化或者布局结构发生改变时,布局过程会被触发。
- 系统会调用每个视图的
layout()
方法来设置视图的位置和大小。
-
调用顺序:
- 系统会从根视图开始,递归调用每个视图的
layout()
方法。 - 在
layout()
方法中,每个视图会根据测量阶段得到的大小信息,计算出自身在父容器中的位置和大小。
- 系统会从根视图开始,递归调用每个视图的
3. Draw(绘制)
绘制阶段是将视图的内容绘制到屏幕上的过程。
-
触发时机:
- 当一个视图需要显示在屏幕上时,绘制过程会被触发。
- 系统会调用每个视图的
draw()
方法来进行实际的绘制操作。
-
调用顺序:
- 系统会从根视图开始,递归调用每个视图的
draw()
方法。 - 在
draw()
方法中,视图会将自己的内容绘制到一个指定的画布(Canvas)上。
- 系统会从根视图开始,递归调用每个视图的
总结
- Measure 阶段确定视图的大小,根据父容器的测量要求计算视图的尺寸。
- Layout 阶段确定视图在父容器中的位置和大小,通过调用
layout()
方法来设置位置信息。 - Draw 阶段将视图的内容绘制到屏幕上,通过调用
draw()
方法来执行绘制操作。
这三个阶段相互配合,确保了 Android 应用程序界面的正确显示和良好的性能。理解这些阶段的工作原理有助于开发者优化界面布局和绘制效率。