转-Android View框架总结(五)View布局流程之Layout

http://blog.csdn.net/hejjunlin/article/details/52216195

 

转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52216195

  • View树的Layout流程
  • View的Layout时序图
  • View布局流程之Layout
    • ViewGroup的Layout过程
    • setFrame方法
    • View的Layout过程
    • FrameLayout的Layout过程

View树的Layout流程图:

这里写图片描述

View布局流程之Layout:

ViewGroup的Layout过程

这里写图片描述

这里写图片描述
这里写图片描述

view.getLeft()——mLeft:子View左边界到 父view左边界的距离
view.getTop()——mTop:子View上边界到父view上边界的距离
view.getRight()—mRight:子View右边界到父view右边界的距离
view.getBottom()—mBottom:子View下边距到父View下边界的距离

ViewGroup的onLayout过程:
这里写图片描述

是一个抽象方法,那么所有ViewGroup的子类都必须重写这个方法。在自定义ViewGroup控件中,onLayout配合onMeasure方法一起使用可以实现自定义View的复杂布局。自定义View首先调用onMeasure进行测量,然后调用onLayout方法动态获取子View和子View的测量大小,然后进行layout布局。重载onLayout的目的就是安排其children在父View的具体位置,重载onLayout通常做法就是写一个for循环调用每一个子视图的layout(l, t, r, b)函数,传入不同的参数l, t, r, b来确定每个子视图在父视图中的显示位置

setFrame方法:

这里写图片描述
这里写图片描述

  • setFrame方法是一个隐藏方法,所以作为应用层程序员来说,无法重写该方法。该方法体内部通过比对本次的l、t、r、b四个值与上次是否相同来判断自身的位置和大小是否发生了改变。
  • 如果发生了改变,将会调用invalidate请求重绘。
  • 位置参数保存在mLeft,mTop,mRight,mBottom中。
  • 如果大小发生了变化,onSizeChanged方法,该方法在大多数View中都是空实现,程序员可以重写该方法用于监听View大小发生变化的事件,在可以滚动的视图中重载了该方法,用于重新根据大小计算出需要滚动的值,以便显示之前显示的区域。

View的Layout过程:
这里写图片描述

这是一个空实现

FrameLayout的Layout过程:
首先,FrameLayout是继承ViewGroup的
onLayout()

这里写图片描述

layoutChildren()

这里写图片描述
这里写图片描述
这里写图片描述

上面getMeasuredWidth及getMeasuredHeight补充:
先看一张图:
这里写图片描述

  • getMeasuredWidth()、getMeasuredHeight()必须在onMeasure之后使用才有效,为什么?如果你没有测量,那你怎么得到这两个值,mMeasuredWidth及mMeasuredHeight就是在onMeasure中赋值的。顺便提下和我们经常用到getWidth(),getHeight()
    • getWidth(): View在设定好布局后整个View的宽度。
    • getMeasuredWidth():View上的內容进行测量后得到的View內容占的宽度
    • view.getMeasuredHeight()可能隐藏在上头.可能在下头.如果view没有超出屏幕的时候view.getMeasuredHeight() 有可能小于 view.getHeight()

    这里写图片描述

总结

layout也是从顶层DecorView向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所得到的布局大小和布局参数,将子View放在合适的位置上。具体有以下几点:

View.layout方法可被重载,ViewGroup.layout为final的不可重载,ViewGroup.onLayout为抽象的,子类必须重载实现自己的告诉父view layout过程。

measure操作完成后得到的是对每个View经测量过的measuredWidth和measuredHeight,layout操作完成之后得到的是对每个View进行位置分配后的mLeft、mTop、mRight、mBottom,这些值都是相对于父View来说的。