博客
关于我
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 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>