布 局 (layout ) 过程
public final void layout(int l, int t, int r, int b) {
/**
* 在 layout()函数中,首先调用setFrame()函数给当前视图设置参数中指定的位置,然后回调onLayoutO
* 函数。 ViewGroup类中重载了 onLayout()函数,并且将其函数类型设置成了一个abstract类型,因此,
* 所 有 的ViewGroup实例必须实现onLayout()。View系统希望程序员能够在onLayout()函数中对该视图所
* 包含的子视图进行layout操作,当该视图是ViewGroup时,程序员一般会在onLayout()函数中调用子视
* 图 child的 layoutO方法,从而完成对子视图的位置分配。当然,如果子视图也是一个ViewGroup实例,
* 就又会调用相应的onLayout()函数。
* 调 用 setFrame(l,t,r,b)将位置参数保存起来,这些参数将保存到View内 部 变 量 (mLeft、 mTop、
* mRight、 mBottom).保存完变量前,会先对比这些参数是否和原来的相同,如果相同,则什么都不做,
* 如果不同才进行重新赋值,并且在赋值前,会 给mPrivateFlags中添加DRAWN标识,同时调用invalidate^
* 告 诉 View系统原来占用的位置需要重绘。注意是先调用invalidateO,而后赋值的,因为需要重绘的是
* 老的区域。
*
*/
boolean changed = setFrame(l, t, r, b);
/**回 调onLayout(), View中定义的onLayout()函数默认什么都不做, View系统提供onLayout()函
数的目的是为了使系统包含有子视图的父视图能够在onLayoutO函数对子视图进行位置分配,正因为如
此 ,如果是父视图,就必须重载onLayout(),也正因为如此, ViewGroup类 才 把onLayout()重载修改为
了一个 abstract 类型。
*/
/**
* 清 除 mPrivateFlags中 的LAYOUT_REQUIRED标识,因 为layout的操作已经完成了。
*/
if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_LAYOUT);
}
onLayout(changed, l, t, r, b);
mPrivateFlags &= ~LAYOUT_REQUIRED;
}
mPrivateFlags &= ~FORCE_LAYOUT;
}