1.布局过程
- 根据测量的尺寸信息,在layout()方法之中进行处理,计算出具体位置信息,并传入至
2.具体开发流程
- ViewGroup重写了onlayout()方法,并且设置方法类型是抽象方法,如果是自定义ViewGroup,则必须重写此方法
- 为每个子View布局计算并传递坐标值
- View不需要重写onlayout()方法
3.View.layout()
- 在测量阶段,最终记录的View尺寸信息,在布局阶段,View.layout()方法把尺寸转为具体的坐标值,并记录至RanderNode,也就是Canvas绘制的起点
- 如果是ViewGroup,则会遍历子View,并设置各个子View的坐标
3.1 源码流程
- 记录当前坐标值
- 设置当前坐标值
- 如果设置了阴影或者发光等属性(只有ViewGroup有),则获取预留尺寸,做尺寸修正,最终调用setFrame()方法
- 否则直接调用setFrame()方法
- setFrame()会将坐标信息记录,并且返回是否改变,如果改变则调用onLayout()方法,传入坐标进行布局
- 设置onLayoutChange回调
- 清空强制布局标记,该标记在measure时判断是否需要onMeasure
3.2 setFrame()
- 如果新的坐标和原始坐标不一致,则重新设置
- 如果新的宽高和原始的宽高不一致,则调用invalidate(sizeChanged),重新执行流程
- 将新的坐标记录至RenderNode(渲染节点,Canvas绘制的起点),最终调用sizeChange()
4.ViewGroup.layout()
- ViewGroup其实也对layout()做了实现,但是只是做了动画处理,最终还是调用了view的layout()
4.1 源码流程
- 如果没有延时布局(没有执行动画),或者动画没有改变坐标,则调用view的layout()
- 如果延时布局,则设置标记位,动画完成后会根据标记位,调用requestLayout()方法,重新发起布局过程