/** * 分析2:setOpticalFrame() * 作用:根据传入的4个位置值,设置View本身的四个顶点位置 * 即:最终确定View本身的位置 */ privatebooleansetOpticalFrame(int left, int top, int right, int bottom){ Insets parentInsets = mParent instanceof View ? ((View) mParent).getOpticalInsets() : Insets.NONE;
Insets childInsets = getOpticalInsets();
// 内部实际上是调用setFrame() return setFrame( left + parentInsets.left - childInsets.left, top + parentInsets.top - childInsets.top, right + parentInsets.left + childInsets.right, bottom + parentInsets.top + childInsets.bottom); } // 回到调用原处
/** * 分析3:onLayout() * 注:对于单一View的laytou过程 * a. 由于单一View是没有子View的,故onLayout()是一个空实现 * b. 由于在layout()中已经对自身View进行了位置计算,所以单一View的layout过程在layout()后就已完成了 */ protectedvoidonLayout(boolean changed, int left, int top, int right, int bottom){
// 参数说明 // changed 当前View的大小和位置改变了 // left 左部位置 // top 顶部位置 // right 右部位置 // bottom 底部位置 }
总结:
layout -> onLayout(空的方法)
三. 多个View,ViewGroup的Layout过程
1. 原理
① 计算 自身ViewGroup的位置:layout
② 遍历子View并且确定子View在ViewGroup的位置(子View的调用layout):onLayout
// 内部实际上是调用setFrame() return setFrame( left + parentInsets.left - childInsets.left, top + parentInsets.top - childInsets.top, right + parentInsets.left + childInsets.right, bottom + parentInsets.top + childInsets.bottom); } // 回到调用原处
/** * 分析3:onLayout() * 作用:计算该ViewGroup包含所有的子View在父容器的位置 * 注: * a. 定义为抽象方法,需重写,因:子View的确定位置与具体布局有关,所以onLayout()在ViewGroup没有实现 * b. 在自定义ViewGroup时必须复写onLayout()!!!!! * c. 复写原理:遍历子View 、计算当前子View的四个位置值 & 确定自身子View的位置(调用子View layout()) */ protectedvoidonLayout(boolean changed, int left, int top, int right, int bottom){
// 参数说明 // changed 当前View的大小和位置改变了 // left 左部位置 // top 顶部位置 // right 右部位置 // bottom 底部位置