UGUI源码解析(二十一)LayoutRebuilder

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq826364410/article/details/88141753

LayoutRebuilder

Graphic是通过MarkLayoutForRebuild这个静态方法标记自己需要重建的。

MarkLayoutForRebuild方法

  • 找到父对象中最近的ILayoutGroup类型的组件layoutRoot,并为其创建LayoutRebuilder。
  • 从s_Rebuilders栈中Pop出一个LayoutRebuilder,s_Rebuilders是一个LayoutRebuilder类型的ObjectPool,调用LayoutRebuilder.Initialize,传入ILayoutGroup类型组件,进行初始化
  • 如果创建的LayoutRebuilder已经在CanvasUpdateRegistry的布局重建序列中,从s_Rebuilders栈中移除创建的LayoutRebuilder。否则,把创建的LayoutRebuilder注册到CanvasUpdateRegistry的布局重建序列中。

LayoutRebuilder继承了ICanvasElement,在CanvasUpdateRegistry中遍历所有注册到它的ICanvasElement类型的组件,调用他们的Rebuild方法。

Rebuild方法

在Rebuild方法中,先调用水平方向的PerformLayoutCalculation和PerformLayoutControl。然后再调用垂直方向的PerformLayoutCalculation和PerformLayoutControl。

PerformLayoutCalculation方法

  • 调用PerformLayoutCalculation,第一个参数m_ToRebuild(就是之前保存在LayoutRebuilder里的layoutRoot),第二个参数传入ILayoutElement.CalculateLayoutInputHorizontal()或ILayoutElement.CalculateLayoutInputVertical(),作为回调函数。
  • 然后以m_ToRebuild的子对象为参数,递归调用PerformLayoutCalculation方法,先计算子对象布局,然后计算父对象布局。
  • 布局计算需要从下往上计算,先计算子对象,然后再计算父对象的布局。因为父对象布局计算依赖子对象的大小。

PerformLayoutControl方法

  • 调用PerformLayoutControl方法,第一个参数m_ToRebuild(就是之前保存在LayoutRebuilder里的layoutRoot),第二个参数传入ILayoutController.SetLayoutHorizontal()或ILayoutController.SetLayoutVertical(),作为回调函数。
  • 在m_ToRebuild节点上,遍历找到的所有的ILayoutController类型的组件components,
  • 先处理components组件中为ILayoutSelfController类型的情况,也就是先处理本身的RectTransform大小设置,
  • 然后处理处理components组件中不是ILayoutSelfController类型的情况,处理比如子对象的布局组(LayoutGroup)的RectTransform大小设置。
  • 然后以m_ToRebuild的子对象为参数,递归调用PerformLayoutControl方法,处理子对象本身的RectTransform大小和子对象的子对象的RectTransform大小。

LayoutComplete方法

把自己从s_Rebuilders中释放,并放入对象池中,以便下次再次使用。在CanvasUpdateRegistry中,会调用所有元素的LayoutComplete方法。

ILayoutController接口

如果一个组件正在驱动它自己的RectTransform,它应该实现接口ILayoutSelfController。如果一个组件正在驱动子组件的RectTransforms,它应该实现ILayoutGroup。

猜你喜欢

转载自blog.csdn.net/qq826364410/article/details/88141753
今日推荐