开发者意见->父view意见->本身去测量->父view拿到实际尺寸位置,调用layout方法布局
运行前,开发者在xml文件写入对view的要求xml
父view在本身的onMeasure中根据开发者在xml中写对子view的要求,和本身的可用空间得出对子view的要求继承
子view在本身的onMeasure中,根据本身的特性算出本身指望的尺寸递归
① 若是是ViewGroup,还会调用每一个子view的measure进行测量开发
父view在子view计算出指望尺寸后,得出子view的实际尺寸和位置get
子view在本身的layout方法中,将父view传进来的本身的实际尺寸和位置保存it
① 若是是VIewGroup,还会在onLayout里面调用每一个子view的layout把它们的尺寸位置传递给他们io
重写onMeasureclass
getMeasuredWidth和getMeasuredSize获取到测量出的尺寸遍历
计算出最终须要的尺寸
setMeasureDimension(width,height)把结果保存
重写onMeasure
计算出本身的尺寸
用resolveSize或则resolveSizeAndState修正结果
内部实现:
① 首先用MeasureSpec.getMode(measureSpec)和MeasureSpec.getSize(MeasureSpec)去出对本身的尺寸限制类型和限制尺寸
② 若是measureSpec的mode是EXACTLY,表示父view对子view的尺寸作出了精的限制,直接用measureSpec的size
③ 若是measureSpec的mode是AT_MOST,表示父view对子view的尺寸只限制了上限,要具体看状况
size不大于spec限制的size,即是没有超限,选用计算出的size
size大于spec限制的size,超限了,选用spec的size
mode是UNSPECIFIED,表示父view对子view没有任何尺寸限制,直接选用计算的size
使用setMeasuredDimension(width,height)保存结果
重写onMeasure
① 遍历每一个子view,用measureChildWidthMargins测量子view
须要重写generateLayoutParams并返回MarginLayoutParams才能使用measureChildWithMargins方法
有些子view须要从新测量 当换行时须要
测量完成后,得出子View的实际位置和尺寸,并暂时保存
① measureChildWidthMargins的内部实现
经过getChildMeasureSpec方法算出子view的widthMeasureSpec和heightMeasureSpec,而后调用child.measure方法让子view自我测量
getChildMeasureSpec方法内部是现实结合开发者设置的LayoutParams中的width和heigth与父view本身的可用空间,得出对子view的限制,并使用MeasureSpec.makeMeasureSpec来求得结果
② 测量出全部子view的位置和尺寸后,计算出本身的尺寸,并用setMeasuredDimension保存
重写onLayout
遍历每一个子view,调用他们的layout方法来将位置和尺寸传给他们
有些父view会对子view进行纠正,如constraintLayout就会强行纠正你自定view的长和宽
通常没人重写layout方法
onLayout负责递归对子view进行赋值,和layout方法不同
测量的过程也能够换一种方法来理解
① 若是开发者写了具体值(例如 layout_width="24dp"),就不用再考虑父View 的剩余空间了,直接用 LayoutParams.width / height 来做为子 View的限制 size,而限制 mode 为 EXACTLY,由于冲突致使界面不正确,开发者能够经过修改 xml 文件来解决,因此开发者的意见是第一位
② 若是开发者写的是 MATCH_PARENT,即要求填满父控件的可用空间,那么因为本身的可用空间和本身的两个 MeasureSpec 有关,因此须要根据本身的 widthMeasureSpec 或 heightMeasureSpec 中的 mode 来分状况判断:
③ 若是开发者写的是 WRAP_CONTENT,即要求子 View 在不超限制的前提下自我测量,那么一样因为本身的可用空间和本身的两个 MeasureSpec 有关,因此也须要根据本身的 widthMeasureSpec 和 heightMeasureSpec中的 mode 来分状况判断: