系列

UGUI源码分析系列总览
相关前置:
UGUI CanvasUpdateSystem源码分析
UGUI源码分析:LayoutSystem布局系统
UGUI源码分析:LayoutGroup中的纵横布局组件

文章目录

  • 系列
  • UML图一览
  • GridLayoutGroup
    • 属性介绍
    • 布局过程
  • ContentSizeFitter
    • 属性介绍
    • 实现过程

UML图一览

GridLayoutGroup

BaseClass: LayoutGroup

Interface: 间接继承了ILayoutElement, ILayoutGroup

Intro:布局系统中的网格布局组件

GridLayoutGroup,是LayoutGroup衍生的用于网格布局的组件,不同于纵横布局,网格布局中严格要求了对子物体尺寸的设置。

属性介绍

  • Padding:内部边距,调整实际用于布局区域的大小
  • Cell Size:子物体尺寸,设置被布局物体的尺寸
  • Spacing :子物体直接的间隔
  • Start Corner :起始位置,子物体起始放置的位置(四个角)
  • Start Axis :起始轴,优先按照横向/纵向排布
  • Child Alignment :子物体对齐方式
  • Constraint :约束类型,可以限制行列数

布局过程

STEP1:依然是延续LayoutRebuilderRebuild方法,大致流程如HorizontalOrVerticalLayoutGroup相似(详情),不同点在于纵横组件只针对自身的单一轴进行布局,而网格组件则要涵盖两条轴上的布局逻辑。首先被执行的是ILayoutElementCalculateLayoutInputHorizontal方法。

public override void CalculateLayoutInputHorizontal()
{//LayoutGroup 基类方法base.CalculateLayoutInputHorizontal();//若对排列有约束限制,则初始化设置参数//这里是横轴则只获取列数的限制//CalculateLayoutInputVertical中则会获取minRowsint minColumns = 0;int preferredColumns = 0;if (m_Constraint == Constraint.FixedColumnCount){minColumns = preferredColumns = m_ConstraintCount;}else if (m_Constraint == Constraint.FixedRowCount){minColumns = preferredColumns = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f);}else{minColumns = 1;preferredColumns = Mathf.CeilToInt(Mathf.Sqrt(rectChildren.Count));}//同HorizontalOrVerticalLayoutGroup组件,初始化参数SetLayoutInputForAxis(padding.horizontal + (cellSize.x + spacing.x) * minColumns - spacing.x,padding.horizontal + (cellSize.x + spacing.x) * preferredColumns - spacing.x,-1, 0);
}

STEP2: GridLayoutGroup的布局实现原理上是与HorizontalOrVerticalLayoutGroup相同的,依靠SetInsetAndSizeFromParentEdge方法实现子物体尺寸与位置的设置。

//执行两条轴的布局
public override void SetLayoutHorizontal()
{SetCellsAlongAxis(0);
}public override void SetLayoutVertical()
{SetCellsAlongAxis(1);
}

这里为了保持阅读舒适度就不贴太长的代码块了,根据设置的参数计算出startOffset(初始位置),cellSize+spacing(尺寸+间隔) 对子物体进行设置。

for (int i = 0; i < rectChildren.Count; i++)
{...SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);
}

ContentSizeFitter

BaseClass: UIBehaviour

Interface: ILayoutSelfController

Intro:布局系统中尺寸调节组件

ContentSizeFitter,是用于调整组件区域使其自适的组件,一般用于与ScrollRect滑动列表以及纵横布局组件搭配,实现动态数量的滑动列表效果,以及与Text组件一起使用,可以根据文字长短进行区域尺寸的变化。

属性介绍

  • Horizontal Fit:水平适应(三种类型:非强制、最小尺寸适应、最佳尺寸适应)
  • Vertical Fit:垂直适应

ContentSizeFitter继承了ILayoutSelfController接口(ILayoutController接口的衍生),和LayoutGroup一样被布局系统所处理。而和LayoutGroup不同的地方在于,ContentSizeFitter不改变子物体的大小和位置,而是根据子物体(ILayoutElement)来改变自身的尺寸。

实现过程

STEP1:ContentSizeFitter Enable阶段会设置布局标记(脏标记),来触发Rebuild

protected override void OnEnable()
{base.OnEnable();SetDirty();
}protected void SetDirty()
{...//封装成LayoutRebuilder等待被重建LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
}

STEP2:当Canvas触发重建过程,其封装成的LayoutRebuilder执行了Rebuild方法。ContentSizeFitter 自身并没有继承ILayoutElement,所有跳过RebuildCalculateLayoutInputHorizontal/Vertical部分,执行了它的SetLayoutHorizontal/Vertical接口方法。

public virtual void SetLayoutHorizontal()
{...//根据轴进行尺寸的改变HandleSelfFittingAlongAxis(0);
}
public virtual void SetLayoutVertical()
{HandleSelfFittingAlongAxis(1);
}
private void HandleSelfFittingAlongAxis(int axis)
{//获取目标轴的适应类型FitMode fitting = (axis == 0 ? horizontalFit : verticalFit);//不强制的类型时不会进行尺寸改变if (fitting == FitMode.Unconstrained){m_Tracker.Add(this, rectTransform, DrivenTransformProperties.None);return;}//添加Tracker的部分无法被修改m_Tracker.Add(this, rectTransform, (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY));//根据类型选择适应的尺寸if (fitting == FitMode.MinSize)rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetMinSize(m_Rect, axis));elserectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetPreferredSize(m_Rect, axis));
}

由上述分析,ContentSizeFitter主要依靠LayoutUtility.GetMinSizeLayoutUtility.GetPreferredSize实现尺寸的变化,这两个方法会从物体自身寻找ILayoutElement,从中获取minWidthpreferredWidth,不存在则返回默认值0
因为ContentSizeFitter自身并未继承ILayoutElement,所以仅仅只有ContentSizeFitter时会将尺寸变为0
如图所示:当垂直适应被选择为Prefered Size时,因为不存在ILayoutElement组件,所以Height被设置成了默认值0

添加LayoutElement组件,并设置Prefered Size 即可看见变化


.
.
.
.
.


嗨,我是作者Vin129,逐儿时之梦正在游戏制作的技术海洋中漂泊。知道的越多,不知道的也越多。希望我的文章对你有所帮助:)


UGUI源码分析:GridLayoutGroup网格布局组件与ContentSizeFitter尺寸调节组件相关推荐

  1. UGUI源码分析:LayoutGroup中的纵横布局组件(HorizontalOrVerticalLayoutGroup)

    系列 UGUI源码分析系列总览 相关前置: UGUI CanvasUpdateSystem源码分析 UGUI源码分析:LayoutSystem布局系统 文章目录 系列 UML图一览 LayoutGro ...

  2. UGUI源码分析:开关组件Toggle与ToggleGroup

    系列 UGUI源码分析系列总览 相关前置: UGUI EventSystem源码分析 UGUI源码分析:Selectable交互组件的基类 文章目录 系列 Toggle Toggle组件属性介绍 初始 ...

  3. [UGUI源码剖析]—Rebuild 网格重建(画布刷新)系统

    几个比较重要的类和接口: Canvas.CanvasUpdateRegistry.ClipperRegistry.LayoutRebuilder.LayoutGroup.Graphics.Maskab ...

  4. UGUI源码解析(LayoutSystem布局系统)

    Runtime类图 ILayoutElement 布局元素接口,是布局的接收方.如果某个类实现了这个接口,那么就会在应用布局时自动完成对它的位置信息及大小的布局计算. ILayoutControlle ...

  5. Android4.2.2 Gallery2源码分析(1)——从布局入手

    使用的是现有的项目的源码进行分析,它在Android原生源码之上有一些修改,主要是添加了一些功能,但整体部分仍然是原生的架构.从零开始,逐步分析. 点开Gallery,进入该程序查看图片,在手机上看到 ...

  6. Tomcat源码分析 | 一文带你整体把握架构及组件

    前言 Tomcat的前身为Catalina,而Catalina又是一个轻量级的Servlet容器.在美国,catalina是一个很美的小岛.所以Tomcat作者的寓意可能是想把Tomcat设计成一个优 ...

  7. 安卓复杂滑动案例 自定义behavior源码分析 实现头布局图片的缩放透明度变化,RecycleView的滑动布局,坐标变化

    #复杂滑动案例 * 上方图片放大, * 透明 * 输入框,不断增大     * 变色 * 滑动的时候,条目不会改变.     * 再滑的时候,条目滑动 #  * 1,让rv居于头部的下方     * ...

  8. UGUI源码解析(二十二)ContentSizeFitter

    ContentSizeFitter类 继承了UIBehaviour, ILayoutSelfController,继承ILayoutSelfController,需要重写SetLayoutHorizo ...

  9. Spring自定义注解驱动开发使用及源码分析

    目录 前言 注解驱动开发使用 需求 代码实现 测试效果 源码分析 BeanDefinitionRegistryPostProcessor接口 解析BeanDefinition 处理Bean上配置的注解 ...

最新文章

  1. 以太坊区块链Ethereum开发资料汇总
  2. python电脑配置要求cpu-Python限制内存和CPU使用量的方法(Unix系统适用)
  3. 整理大型网站架构必知必会的几个服务器知识
  4. 代码生成工具的分类及比较
  5. android 输入光标修改颜色_2.2 输入数值与文本
  6. 十三、手把手带你搭建Clouders Manager
  7. 【渝粤教育】国家开放大学2019年春季 2732土地利用规划 参考试题
  8. Java8————Base64
  9. Spring Boot(十三):整合Redis哨兵,集群模式实践
  10. IIS6.0目录解析漏洞原理/复现
  11. 【matlab选题推荐三】基于MATLAB的答题卡自动阅卷记分系统
  12. Web服务器性能压力测试工具
  13. 上海计算机应用基础自考上机,上海市自学考试公共实践课程《计算机应用基础(实践)》上机考核大纲_自考资讯自考_自考报名_中国教育在线...
  14. 二进制模2除法(CRC循环冗余检验)
  15. 和橘子菇凉一起开始python之旅吧!
  16. java屏蔽虚拟按键代码_Android 中隐藏虚拟按键的方法实例代码
  17. FreeBSD 虚拟化(jail) 初体验
  18. Oracle Database 10g for Windows2003安装
  19. Prometheus监控告警规则
  20. 怎么删除批注mysql_如何去掉 Word 文档修订和批注和不显示已删除内容

热门文章

  1. 艾永亮:企业微信,私域流量“后时代”的开启者
  2. Python 从入门到爬虫极简教程
  3. uniapp微信浏览器H5授权微信登录
  4. 关于ios包破解激活码(一机一码)以及添加激活码(一机一码)大神进!!
  5. Web服务器群集——编译安装Nginx-1.16及虚拟主机配置
  6. npm start 报错解决方案
  7. Ubuntu安装Node.js(亲测,最新,详细)
  8. anaconda更改虚拟环境安装位置
  9. 如何在推荐系统中玩转知识图谱
  10. Geophysical research letters 进度2