Android应用的用户界面中,我们经常需要自定义View以满足特定的设计需求。在自定义视图的过程中,理解视图的测量(onMeasure
)和布局(onLayout
)过程至关重要。本篇博客将用通俗的语言,为你解析这两个关键步骤,帮助你更好地理解Android视图的绘制。
在我们绘制一个视图之前,Android系统需要知道这个视图的大小。测量的目的就是告诉系统,我们期望这个视图的尺寸是多少。
onMeasure测量阶段:
首先一个View的measure()方法会被它的父View调用,这个方法的作用是让这个View进行自我测量,不过真正进行自我测量的不是measure()方法,而是在measure()方法内部调用的onMeasure()方法,measure()是一个调度方法,它会做一些测量的预处理工作,然后去调用onMeasure()来进行真正的自我测量,这个自我测量包含什么内容呢?
分两种情况:
1.它是View
如果它就是一个View,是没有子View的,那么它做的事就只有一件:计算出自己的尺寸。如图所示:
2.它是ViewGroup
如果它是一个ViewGroup是有子View的,ViewGroup会先调用它的所有子View的measure()方法,让它们都进行自我测量。然后根据这些子View自我测量出的尺寸来计算出ViewGroup的位置,并且把子View的尺寸和位置保存下来,同时ViewGroup还会根据这些子View的尺寸和位置,最终得出自己的尺寸。总的来说,ViewGroup的尺寸都主要是由自己所有子View的尺寸和位置来确定的。如图所示:
onLayout布局阶段:
每一个View或者ViewGroup也会被父View调用它的layout()方法,这个方法会对View进行内部布局,不过和measure()一样的layout()也只是一个调度方法,它在内部会做两件事:
第一件事:
首先layout()这个方法是有参数的,它的父View在调用它的时候,会把之前在测量阶段保存下来的这个子View的尺寸和位置 ,通过参数给传进来,而layout()方法会把传进来的这个尺寸和位置保存下来,测量阶段是父View统一保存所有子View的位置和尺寸,而到了布局阶段就是子View自己来保存了。
第二件事:
layout()会去调用自己的onLayout()方法,在这个onLayout()里面,它会真正的对自己进行内部布局,这个内部布局的意思就是去调用它的每一个子View的layout()方法,并且把它们的位置和尺寸作为参数给传进去让它们自己进行自我布局,这个就是所谓的内部布局。也就是根据测量结果来摆放所有子View的意思。
1.对于View。显然对于View来说onLayout()是什么也不用干的,因为它没有子View。如图所示:
2.对于ViewGroup。onLayout()就会真正地去调用每个子View的layout()方法,然后把子View的位置和尺寸传进去。如图所示: