博客
关于我
UGUI文图混合排列问题——Horizontal Layout Group和Content Size Fitter
阅读量:507 次
发布时间:2019-03-07

本文共 6724 字,大约阅读时间需要 22 分钟。

前言

最近在工作中遇到了UGUI文图混合排列的问题,查阅相应资料后发现添加Horizontal Layout Group组件和Content Size Fitter组件就可以实现自动居中的效果。想半天没想明白是什么原理,于是打算深入探究这两个组件的魔力。


Horizontal Layout Group

先看Horizontal Layout Group组件。

这是Horizontal Layout Group组件的官方源码。

namespace UnityEngine.UI{       [AddComponentMenu("Layout/Horizontal Layout Group", 150)]    ///     /// Layout class for arranging child elements side by side.    ///     public class HorizontalLayoutGroup : HorizontalOrVerticalLayoutGroup    {           protected HorizontalLayoutGroup()        {   }        ///         /// Called by the layout system. Also see ILayoutElement        ///         public override void CalculateLayoutInputHorizontal()        {               base.CalculateLayoutInputHorizontal();            CalcAlongAxis(0, false);        }        ///         /// Called by the layout system. Also see ILayoutElement        ///         public override void CalculateLayoutInputVertical()        {               CalcAlongAxis(1, false);        }        ///         /// Called by the layout system. Also see ILayoutElement        ///         public override void SetLayoutHorizontal()        {               SetChildrenAlongAxis(0, false);        }        ///         /// Called by the layout system. Also see ILayoutElement        ///         public override void SetLayoutVertical()        {               SetChildrenAlongAxis(1, false);        }    }}

我们可以看到Horizontal Layout Group继承的是HorizontalOrVerticalLayoutGroup,而HorizontalOrVerticalLayoutGroup继承的又是LayoutGroup。因此Horizontal Layout Group具有所有LayoutGroup的通用特性,和Vertical Layout Group、Grid Layout Group十分相似。

Horizontal Layout Group中有几个基本属性,如Padding、Spacing、Child Alignment、Child Force Expand,新版本还添加了两个新属性。

Padding

实际上就是边界留空。它包括上下左右四个边界,分别可以调整其子物体内容与边界之间的距离。

Spacing

实际上指的是其子物体之间的距离。

Child Alignment

即子物体的对其方式,有上左、上中、上右、中左、中中、中右、下左、下中、下右。

Child Force Expand

即子物体是否需要通过拉伸来强制填充满父物体。可以选择宽填充,也可以选择高填充,还可以都选或都不选。

Horizontal Layout Group之所以能够自动排布子物体,关键就在于它本质是个Layout Group。也就是说对于它所有的子物体都会进行等距离排布。因此子物体是Text还是Image都可以很工整地处理。


Content Size Fitter

再看Content Size Fitter组件。

这是Content Size Fitter组件的官方源码。

using UnityEngine.EventSystems;namespace UnityEngine.UI{       [AddComponentMenu("Layout/Content Size Fitter", 141)]    [ExecuteAlways]    [RequireComponent(typeof(RectTransform))]    ///     /// Resizes a RectTransform to fit the size of its content.    ///     /// 
/// The ContentSizeFitter can be used on GameObjects that have one or more ILayoutElement components, such as Text, Image, HorizontalLayoutGroup, VerticalLayoutGroup, and GridLayoutGroup. ///
public class ContentSizeFitter : UIBehaviour, ILayoutSelfController { /// /// The size fit modes avaliable to use. /// public enum FitMode { /// /// Don't perform any resizing. /// Unconstrained, /// /// Resize to the minimum size of the content. /// MinSize, /// /// Resize to the preferred size of the content. /// PreferredSize } [SerializeField] protected FitMode m_HorizontalFit = FitMode.Unconstrained; /// /// The fit mode to use to determine the width. /// public FitMode horizontalFit { get { return m_HorizontalFit; } set { if (SetPropertyUtility.SetStruct(ref m_HorizontalFit, value)) SetDirty(); } } [SerializeField] protected FitMode m_VerticalFit = FitMode.Unconstrained; /// /// The fit mode to use to determine the height. /// public FitMode verticalFit { get { return m_VerticalFit; } set { if (SetPropertyUtility.SetStruct(ref m_VerticalFit, value)) SetDirty(); } } [System.NonSerialized] private RectTransform m_Rect; private RectTransform rectTransform { get { if (m_Rect == null) m_Rect = GetComponent
(); return m_Rect; } } private DrivenRectTransformTracker m_Tracker; protected ContentSizeFitter() { } protected override void OnEnable() { base.OnEnable(); SetDirty(); } protected override void OnDisable() { m_Tracker.Clear(); LayoutRebuilder.MarkLayoutForRebuild(rectTransform); base.OnDisable(); } protected override void OnRectTransformDimensionsChange() { SetDirty(); } private void HandleSelfFittingAlongAxis(int axis) { FitMode fitting = (axis == 0 ? horizontalFit : verticalFit); if (fitting == FitMode.Unconstrained) { // Keep a reference to the tracked transform, but don't control its properties: m_Tracker.Add(this, rectTransform, DrivenTransformProperties.None); return; } m_Tracker.Add(this, rectTransform, (axis == 0 ? DrivenTransformProperties.SizeDeltaX : DrivenTransformProperties.SizeDeltaY)); // Set size to min or preferred size if (fitting == FitMode.MinSize) rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetMinSize(m_Rect, axis)); else rectTransform.SetSizeWithCurrentAnchors((RectTransform.Axis)axis, LayoutUtility.GetPreferredSize(m_Rect, axis)); } ///
/// Calculate and apply the horizontal component of the size to the RectTransform /// public virtual void SetLayoutHorizontal() { m_Tracker.Clear(); HandleSelfFittingAlongAxis(0); } ///
/// Calculate and apply the vertical component of the size to the RectTransform /// public virtual void SetLayoutVertical() { HandleSelfFittingAlongAxis(1); } protected void SetDirty() { if (!IsActive()) return; LayoutRebuilder.MarkLayoutForRebuild(rectTransform); } #if UNITY_EDITOR protected override void OnValidate() { SetDirty(); } #endif }}

Content Size Fitter从本质上来说就是可以自动根据物体内容来自动适配物体的大小。

可以调整水平适配和垂直适配,分别有三个调整选项,Unconstrainted、MinSize和PreferredSize。

Unconstrainted

是指物体不根据布局和内容来调整大小,因此需要手动来进行调整。

Minsize

是指物体根据布局的最小值来调整大小。

PreferredSize

是指物体根据内容来调整大小。

总的来说,这个组件经常与任意一种Layout Group组件一起使用,因为无论添加多少子物体都可以自动对父物体进行布局和大小控制。特别方便,特别实用。


总结

UGUI布局问题解决方式其实有很多种,Unity自带的UI组件有很多,这里列出的方法仅仅只是其中一种,也是比较常见的一种。所以一定要不断的学习,遇到问题的时候一定要去挖它的底层原理,只有知道底层才算是真正的知道问题。


因为本人也还在学习过程中,所以肯定有很多地方考虑不全,以及会有很多错误。希望有大佬看到能够及时指出,我会立刻进行改正,帮助我自己和大家共同进步!

有问题的小伙伴们可以在下方留言,大家可以一起讨论。

转载地址:http://hkxcz.baihongyu.com/

你可能感兴趣的文章
Mysql 分页语句 Limit原理
查看>>
MySQL 创建新用户及授予权限的完整流程
查看>>
mysql 创建表,不能包含关键字values 以及 表id自增问题
查看>>
mysql 删除日志文件详解
查看>>
mysql 判断表字段是否存在,然后修改
查看>>
mysql 协议的退出命令包及解析
查看>>
mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
查看>>
mysql 多个表关联查询查询时间长的问题
查看>>
mySQL 多个表求多个count
查看>>
mysql 多字段删除重复数据,保留最小id数据
查看>>
MySQL 多表联合查询:UNION 和 JOIN 分析
查看>>
MySQL 大数据量快速插入方法和语句优化
查看>>
mysql 如何给SQL添加索引
查看>>
mysql 字段区分大小写
查看>>
mysql 字段合并问题(group_concat)
查看>>
mysql 字段类型类型
查看>>
MySQL 字符串截取函数,字段截取,字符串截取
查看>>
MySQL 存储引擎
查看>>
mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
查看>>
MySQL 存储过程参数:in、out、inout
查看>>