本文节选自洪流学堂公众号专栏《郑洪智的Unity2018课》,未经允许不可转载。
洪流学堂公众号回复专栏
,查看更多专栏文章。
小新:“大智,我在往Scroll View里面填充内容的时候,感觉布局很难设置啊,都需要手动来设置他们的坐标么?”
大智:“手动设置坐标是一种方式,还有一种方式是使用自动布局,自动排列。”
小新:“那今天教教我怎么设置自动布局吧,我这手动设置的要吐了”
大智:“没问题呀”
AutoLayout自动布局
RectTransform给UI的布局提供了很大的灵活性,但是有些情况下我们需要一些结构化的布局,比如列表、表格等内容。
自动布局系统提供了多种自动布局的方式,比如横向、竖向或网格状;UI元素也可以根据内容的多少动态调整UI元素自身的尺寸。例如按钮可以动态的根据按钮的文字多少调整大小。
自动布局系统基于RectTransform,可以用于全部或部分UI元素。
自动布局的概念
自动布局系统中非常重要的两个概念是:布局元素和布局控制器。
布局元素就是参与自动布局的UI元素,最基本需要是一个GameObject上面有一个RectTransform组件,这个物体上也可以有其他组件。布局元素知道自己的尺寸应该是多大。布局元素不直接设置自己的尺寸,但是给布局控制器提供布局所需要的信息来计算他们的尺寸和位置。
一个布局元素包含的属性包括:
- Minimum width 最小宽度
- Minimum height 最小高度
- Preferred width 最佳宽度
- Preferred height 最佳高度
- Flexible width 弹性宽度
- Flexible height 弹性高度
任何拥有RectTransform组件的GameObject都是一个布局元素,它的这6个属性默认情况都是0。一些组件可以改变这些属性的值。比如Image和Text组件,会改变preferred width 和 height来匹配Sprite或文本内容。
一个GameObject的布局元素属性可以通过下图的方式查看:
一个参与自动布局的UI确定尺寸的过程如下:
- 先分配最小尺寸
- 如果还有富余的空间,分配最佳尺寸
- 如果还有额外的空间,分配弹性尺寸
LayoutElement组件
如果你想重写设置最小、最佳、弹性尺寸,你可以给物体添加LayoutElement组件。
组件属性
Ignore Layout 选中后该物体不参与自动布局,可以手动设置该物体的位置。
如果想修改下面的属性,选中后面的复选款,然后填入对应的值即可
Min Width 最小宽度
Min Height 最小高度
Preferred Width 最佳宽度
Prefered Height 最佳高度
Flexible Width 弹性宽度
Flexible Height 弹性高度
Layout Priority 布局优先级,保持默认值即可
Minimum 和 preferred 尺寸的单位是像素,但是flexible尺寸是一个相对大小(权重)。所有flexible数值大于0的UI会分配额外的弹性尺寸,这个flexible尺寸决定了给UI分配的弹性空间的比例。flexible越大,分配的空间相对越大。一般情况下,flexible尺寸会设置为0或1。
比如4个UI元素的flexible高度都是1,在分配完prefered尺寸后高度空间还有100弹性空间,则4个元素会平均分配弹性空间,每个25。但是假如有1个UI的flexible是2,这个UI会被分配到的弹性空间是2/(2+1+1+1)*100,也就是40像素。
有些情况下可以同时指定preferred尺寸和flexible尺寸。所有UI元素的preferred尺寸都分配后,才会分配弹性空间。如果一个元素设置了弹性尺寸,但是没有设置prefered尺寸,会在其他兄弟物体的都分配到prefered尺寸后才开始分配弹性尺寸。
布局控制器
布局控制器用来控制自动布局元素的尺寸和位置。有的布局控制器可以控制自身的尺寸,有的可以控制子物体的布局。
有的布局控制器本身也有布局元素的功能。
Content Size Fitter 组件
Content Size Fitter组件可以控制自身的布局属性。
查看Content Size Fitter组件生效的最直观的方式是给Text组件添加Content Size Fitter组件。设置Horizontal或Vertical为Preferred,你就会看到Text的矩形框随着文本的内容变化而变化。
Aspect Ratio Fitter 组件
Aspect Ratio Fitter 组件可以控制自身的布局。
Aspect Mode
- None 不设置,相当于该组件不生效
- Width Controls Height 宽度控制高度。高度会根据宽度和宽高比(Aspect Ratio)设置。
- Height Controls Width 高度控制宽度。宽度会根据高度和宽高比(Aspect Ratio)设置。
- Fit In Parent Unity会根据Ratio,自动调整物体的width,height,位置和锚点来让这个物体尽量充满父物体,但是可能无法完全覆盖父物体的尺寸。注意自动设置的位置是根据该物体的pivot位置。
- Envelope Parent Unity会根据Ratio,自动调整物体的width,height,位置和锚点来让这个物体在尺寸尽量小的情况下覆盖父物体,但是很大可能超出父物体的范围。注意自动设置的位置是根据该物体的pivot位置。
LayoutGroup组件
LayoutGroup组件包括 Horizontal Layout Group, Vertical Layout Group 和Grid Layout Group三个组件。
LayoutGroup组件的功能是控制子物体的尺寸和位置。
- Horizontal Layout Group 横向排列子物体
- Vertical Layout Group 纵向排列子物体
- Grid Layout Group 网格排列子物体
LayoutGroup组件并不控制自身的布局属性,可以使用上面提到的组件自动控制或手动设置。
LayoutGroup组件可以任意组合嵌套。
Horizontal Layout Group
Horizontal Layout Group将子物体横向布局。根据以下规则,它们的宽度由各自的最小宽度,最佳宽度和弹性宽度决定:
- 将所有子物体的最小宽度相加,并且加上间距Spacing。结果是Horizontal Layout Group的最小宽度。
- 所有子物体的最佳宽度相加,并且加上间距。结果是Horizontal Layout Group的最佳宽度。
- 如果Horizontal Layout Group的宽度小于等于最小宽度,则所有子物体也将是其最小宽度。
- Horizontal Layout Group的宽度越接近其最佳宽度,每个子物体也越接近其最佳宽度。
- 如果Horizontal Layout Group的宽度大于其最佳宽度,则它将根据各自的弹性宽度按比例分配额外可用空间到子物体。
Padding 内边距
Spacing 元素之间的间距
Child Alignment 子物体的对齐方式
Child Controls Size 子物体是否自己控制自己的尺寸
Child Force Expand 是否强制子物体拉伸来充满所有的可用空间。
Vertical Layout Group
Vertical Layout Group将子物体竖向布局。规则和Horizontal Layout Group相似。
Grid Layout Group
Grid Layout Group将子物体网格布局。
和水平/垂直布局不同,Grid布局忽略子物体的minimum, preferred, flexible属性,使用Cell Size来设置他们的尺寸。
Padding 内边距
Cell Size 子物体的尺寸
Spacing 子物体之间的间距
Start Corner 第一个元素布局的位置
Start Axis 布局的方向,是横向还是竖向
Child Alignment 子物体对其的方式
Constraint 给Grid设置一些约束(股东行数/列数),来辅助自动布局系统
Grid Layout Group和自动布局
在将Grid Layout Group用作自动布局设置的一部分时,需要注意一些特殊事项,例如将其与 Content Size Fitter一起使用的情况。
自动布局系统独立计算水平和垂直尺寸。这可能与Grid Layout Group不一致,其行数取决于列数,反之亦然。
对于任何给定数量的单元格,行数和列数的不同组合可以使网格适合其尺寸。为了能使用自动布局系统,你可以使用Constraint属性指定固定数量的列或行。
以下是使用Content Size Fitter的布局系统的建议方法:
灵活的宽度和固定的高度
要设置具有灵活宽度和固定高度的网格,网格随着添加更多元素而水平扩展,你可以按如下方式设置这些属性:
- Grid Layout Group Constraint: Fixed Row Count
- Content Size Fitter Horizontal Fit: Preferred Size
- Content Size Fitter Vertical Fit: Preferred Size 或 Unconstrained
如果Vertical Fit设置为unconstrained,则需要设置Grid的height以适合指定的单元格行数。
固定宽度和灵活的高度
要设置具有固定宽度和灵活高度的网格,网格在添加更多元素时垂直扩展,你可以按如下方式设置这些属性:
- Grid Layout Group Constraint: Fixed Column Count
- Content Size Fitter Horizontal Fit: Preferred Size 或 Unconstrained
- Content Size Fitter Vertical Fit: Preferred Size
如果Horizontal Fit设置为unconstrained,则需要设置Grid的width以适合指定的单元格行数。
灵活的宽度和高度
如果你希望网格具有灵活的宽度和高度,则可以按照下面设置,但你无法控制特定的行数和列数。网格将尝试使行和列计数大致相同。
- Grid Layout Group Constraint: Flexible
- Content Size Fitter Horizontal Fit: Preferred Size
- Content Size Fitter Vertical Fit: Preferred Size
总结
大智:“今天学习了UI的自动布局,很多情况下使用自动布局会使UI的布局更容易,更简单,但是前提是要深刻理解这些自动布局组件,否则自动布局也会出现很多奇怪的问题。”
小新:“那什么时候适合使用自动布局呢?”
大智:“自动布局适合大量UI的布局,并且这些UI的排列有一定的规律。”
今日思考题
大智:“你现在可以尝试实现一个排行榜、好友列表或者聊天对话框了!”
小新:“好嘞”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”
洪流学堂公众号回复专栏
,查看更多专栏文章。