系列
UGUI源码分析系列总览
相关前置:
UGUI CanvasUpdateSystem源码分析
UGUI源码分析:LayoutSystem布局系统
文章目录
UML图一览
LayoutGroup
BaseClass: UIBehaviour
Interface: ILayoutElement, ILayoutGroup
Intro:布局系统的实施组件的基类
虽然UGUI组件中有一些组件都继承了ILayoutElement接口,但并不会涉及对接口方法的实现。这是因为这些组件主要是布局操作的接收方,只需要通过该接口被布局实施方所发现即可。
LayoutGroup,是布局组件的基类(GridLayoutGroup、HorizontalOrVerticalLayoutGroup)。本文主要针对纵横布局组件(HorizontalLayoutGroup、VerticalLayoutGroup)进行分析。
属性介绍
- Padding:内部边距,调整实际用于布局区域的大小
- Spacing :子物体直接的间隔
- Child Alignment :子物体对齐方式
- Child Controls Size :组件控制子物体尺寸开关,开启时组件可以更改物体尺寸。
- Child Force Expand :组件控制子物体填充区域开关,若可以修改尺寸则会改变子物体尺寸填充区域,若不可以修改尺寸,则根据区域大小均衡分布子物体。
布局过程
接下来,作者以HorizontalLayoutGroup为例,逐步进行布局实现的分析。
延续LayoutRebuilder的Rebuild方法(详情:UGUI源码分析:LayoutSystem布局系统),首先被执行的是ILayoutElement的CalculateLayoutInputHorizontal方法。该方法将收集其子节点下所有没有被标记ignoreLayout的物体(m_RectChildren)。
// HorizontalLayoutGroup
public override void CalculateLayoutInputHorizontal()
{
// 基类(LayoutGroup)方法
base.CalculateLayoutInputHorizontal();
CalcAlongAxis(0, false);
}
//LayoutGroup
public virtual void CalculateLayoutInputHorizontal()
{
//清空list,准备收集子节点下没有被ignoreLayout的物体
m_RectChildren.Clear();
var toIgnoreList = ListPool<Component>.Get();
for (int i = 0; i < rectTransform.childCount; i++)
{
var rect = rectTransform.GetChild(i) as RectTransform;
if (rect == null || !rect.gameObject.activeInHierarchy)
continue;
rect.GetComponents(typeof(ILayoutIgnorer), toIgnoreList);
if (toIgnoreList.Count == 0)
{
m_RectChildren.Add(rect);
continue;
}
for (int j = 0; j < toIgnoreList.Count; j++