Unity2017.1官方UGUI文档翻译——Auto Layout
Auto Layout
The Rect Transform layout system is flexible enough to handle a lot of different types of layouts and it also allows placing elements in a complete freeform fashion. However, sometimes something a bit more structured can be needed.
Rect Transfrom 布局系统足够灵活来处理各种不同的布局,而且它允许你把元素完全自由地放置。然而,有时候需要一些更结构化的东西。
The auto layout system provides ways to place elements in nested layout groups such as horizontal groups, vertical groups, or grids. It also allows elements to automatically be sized accoring to the contained content. For example a button can be dynamically resized to exactly fit its text content plus some padding.
自动布局系统提供了把元素放到嵌套的布局组(比如水平布局组、垂直布局组、网格)中的方法。它同样允许元素自动根据内容的大小来确定自己的大小。比如按钮可以动态地改变自己的大小,完全贴合他的文字内容加上边距的大小。
The auto layout system is a system built on top of the basic Rect Transform layout system. It can optionally be used on some or all elements.
自动布局系统是在基础的Rect Transform布局系统地基础上搭建的。它可以选择性地被全部或部分元素使用。
Understanding Layout Elements
理解布局元素
The auto layout system is based on a concept of layout elements and layout controllers. A layout element is an Game Object with a Rect Transform and optionally other components as well. The layout element has certain knowledge about which size it should have. Layout elements don’t directly set their own size, but other components that function as layout controllers can use the information they provide in order to calculate a size to use for them.
自动布局系统基于布局元素和布局控制器的概念,一个布局元素是一个带有Rect Transform的GameObject,也可以带有其它组件。布局元素一定知道它自己应该有多大。布局元素不会直接设置自己的大小,但是其他功能像布局控制器一样的组件可以使用他们提供的信息来计算出他们的大小。
A layout element has properties that defines its own:
- Minimum width
- Minimum height
- Preferred width
- Preferred height
- Flexible width
- Flexible height
布局元素有它自己定义的属性
- 最小宽度
- 最小高度
- 首选宽度
- 首选高度
- 灵活宽度
- 灵活高度
Examples of layout controller components that use the information provided by layout elements are Content Size Fitter and the various Layout Group components. The basic principles for how layout elements in a layout group are sized is as follows:
- First minimum sizes are allocated.
- If there is sufficient available space, preferred sizes are allocated.
- If there is additional available space, flexible size is allocated.
布局控制器组件使用布局元素提供的信息的例子是,各种各样的Layout Group(布局组)和内容尺寸适配。布局元素在布局组中如何确定尺寸的基本原则如下:
- 首先申请最小的尺寸
- 如果这里有足够的可用空间,那么就申请首选尺寸
- 如果还有额外的可用空间,那么就申请灵活尺寸
Any Game Object with a Rect Transform on it can function as a layout element. They will by default have minimum, preferred, and flexible sizes of 0. Certain components will change these layout properties when added to the Game Object.
The Image and Text components are two examples of components that provide layout element properties. They change the preferred width and height to match the sprite or text content.
所有有Rect Transform的Game Object可以被当做layout element(布局元素)来使用。他们默认的最小、首选、灵活尺寸都是0。某些组件在添加到Game Object上的时候会改变这些布局属性。
Image和Text组件式两个组件提供布局元素属性的例子。他们改变首选宽度和高度来匹配精灵和文字的内容。
Layout Element Component
布局元素组件
If you want to override the minimum, preferred, or flexible size, you can do that by adding a Layout Element component to the Game Object.
如果你想重写最小、首选、灵活尺寸,你可以添加一个 Layout Element component(布局元素组件)到Game Object
The Layout Element component lets you override the values for one or more of the layout properties. Enable the checkbox for a property you want to override and then specify the value you want to override with.
布局元素组件让你可以覆盖一个或多个布局属性的值。勾选你想要覆盖的属性的复选框,然后指定你想要覆盖的值
See the reference page for Layout Element for more information.
更多信息可以看Layout Element的介绍页面
Understanding Layout Controllers
理解布局控制器
Layout controllers are components that control the sizes and possibly positions of one or more layout elements, meaning Game Objects with Rect Transforms on. A layout controller may control its own layout element (the same Game Object it is on itself) or it may control child layout elements.
A component that functions as a layout controller may also itself function as a layout element at the same time.
布局控制器是一个可以控制一个或多个布局元素的尺寸或者大小的组件。一个布局控制器可能控制它自己GameObject上的布局元素(就是控制它自己脚本所在的节点),或者子节点的布局元素。
一个有布局控制器功能的组件也可能同时有布局元素的功能。
Content Size Fitter
内容尺寸适配器
The Content Size Fitter functions as a layout controller that controls the size of its own layout element. The simplest way to see the auto layout system in action is to add a Content Size Fitter component to a Game Object with a Text component.
Content Size Fitter是一个控制自身布局元素尺寸的布局控制器。如果想看看自动布局系统的行为,最简单的方法是将一个Content Size Fitter组件添加到包含Text组件的游戏对象中。
If you set either the Horizontal Fit or Vertical Fit to Preferred, the Rect Transform will adjust its width and/or height to fit the Text content.
如果你设置水平和垂直适配到首选,Rect Transform会调整它的宽度和高度适配文本内容
See the reference page for Content Size Fitter for more information.
更多信息可以看Content Size Fitter的介绍页面
Aspect Ratio Fitter
长宽比适配器
The Aspect Ratio Fitter functions as a layout controller that controls the size of its own layout element.
长宽比适配器是一个控制自身布局元素尺寸的布局控制器。
It can adjust the height to fit the width or vice versa, or it can make the element fit inside its parent or envelope its parent. The Aspect Ratio Fitter does not take layout information into account such as minimum size and preferred size.
它可以调整高度以适应宽度,反之亦然,或者它可以适应到父节点内或者包裹父节点。长宽比适配器不会考虑到布局信息,比如最小尺寸和首选尺寸。
See the reference page for Aspect Ratio Fitter for more information.
更多信息可以看Aspect Ratio Fitter的介绍页面
Layout Groups
布局组
A layout group functions as a layout controller that controls the sizes and positions of its child layout elements. For example, a Horizontal Layout Group places its children next to each other, and a Grid Layout Group places its children in a grid.
布局组作为布局控制器控制子布局元素的尺寸和位置。例如,水平布局组把它的孩子一个挨着一个排列,网格布局组把它的子节点放到网格中。
A layout group doesn’t control its own size. Instead it functions as a layout element itself which may be controlled by other layout controllers or be set manually.
布局组不会控制自己的尺寸。相反,它作为布局元素本身,可以由其他布局控制器控制或手动设置。
Whatever size a layout group is allocated, it will in most cases try to allocate an appropriate amount of space for each of its child layout elements based on the minimum, preferred, and flexible sizes they reported. Layout groups can also be nested arbitrarily this way.
无论布局组分配了多少大小,在大多数情况下它会基于子布局元素提供的最小、首选、灵活尺寸来为它们分配适当的空间。布局组也可以这样任意嵌套。
See the reference pages for Horizontal Layout Group, Vertical Layout Group and Grid Layout Group for more information.
更多信息可以看Horizontal Layout Group,Vertical Layout Group和Grid Layout Group的介绍页面
Driven Rect Transform properties
Since a layout controller in the auto layout system can automatically control the sizes and placement of certain UI elements, those sizes and positions should not be manually edited at the same time through the Inspector or Scene View. Such changed values would just get reset by the layout controller on the next layout calculation anyway.
因为自动布局系统的布局控制器能够自动调整某些UI元素的尺寸和位置,所以这些尺寸和位置不应在Inspector或场景视图中手动修改。布局控制器在下一次布局计算中就会重新这些修改过的值(所以手动修改是没有用的)
The Rect Transform has a concept of driven properties to address this. For example, a Content Size Fitter which has the Horizontal Fit property set to Minimum or Preferred will drive the width of the Rect Transform on the same Game Object. The width will appear as read-only and a small info box at the top of the Rect Transform will inform that one or more properties are driven by Conten Size Fitter.
Rect Transform由driven properties(属性驱动)来达到此效果。例如,把Content Size Fitter的Horizontal Fit属性设置为Minimum或Preferred会驱动自身GameObject上Rect Transform的宽度。宽度会显示为只读,Rect Transform顶部的小信息窗会标识一个或多个属性被Content Size Fitter驱动
The driven Rect Transforms properties have other reasons beside preventing manual editing. A layout can be changed just by changing the resolution or size of the Game View. This in turn can change the size or placement of layout elements, which changes the values of driven properties. But it wouldn’t be desirable that the Scene is marked as having unsaved changes just because the Game View was resized. To prevent this, the values of driven properties are not saved as part of the Scene and changes to them do not mark the scene as changed.
这些被驱动的Rect Transform中的属性除了防止被手动修改还有别的原因,调整Game视图的分辨率或尺寸布局就会改变,这些反过来会改变布局元素的尺寸和位置,这就会改变被驱动的属性值。但是因为Game视图大小改变就会导致Scene被标记为未保存,这不是我们想要的。为了防止这种情况发生,驱动属性的值不会保存为Scene的一部分,对其进行更改不会将Scene标记为已更改。
Technical Details
技术细节
The auto layout system comes with certain components built-in, but it is also possible to create new components that controls layouts in custom ways. This is done by having a component implement specific interfaces which are recognized by the auto layout system.
自动布局系统附带了一些内置组件,但是也可以创建以自定义方式控制布局的新组件。这是通过让一个组件实现可被自动布局系统识别的特定接口来完成的。
Layout Interfaces
布局接口
A component is treated as a layout element by the auto layout system if it implements the interface ILayoutElement.
如果一个组件实现了ILayoutElement接口,他会被自动布局系统当做布局元素
A component is expected to drive the Rect Transforms of its children if it implements the interface ILayoutGroup.
如果一个组件实现了接口ILayoutGroup,那么它将会驱动子组件的RectTransform
A component is expected to drive its own RectTransform if it implements the interface ILayoutSelfController.
如果一个组件实现了接口ILayoutSelfController,那么它将会驱动它自己的RectTransform
Layout Calculations
布局计算
The auto layout system evaluates and executes layouts in the following order:
自动布局系统按以下顺序评估和执行布局:
- The minimum, preferred, and flexible widths of layout elements are calculated by calling CalculateLayoutInputHorizontal on ILayoutElement components. This is performed in bottom-up order, where children are calculated before their parents, such that the parents may take the information in their children into account in their own calculations.
- The effective widths of layout elements are calculated and set by calling SetLayoutHorizontal on ILayoutController components. This is performed in top-down order, where children are calculated after their parents, since allocation of child widths needs to be based on the full width available in the parent. After this step the Rect Transforms of the layout elements have their new widths.
- The minimum, preferred, and flexible heights of layout elements are calculated by calling CalculateLayoutInputVertical on ILayoutElement components. This is performed in bottom-up order, where children are calculated before their parents, such that the parents may take the information in their children into account in their own calculations.
- The effective heights of layout elements are calculated and set by calling SetLayoutVertical on ILayoutController components. This is performed in top-down order, where children are calculated after their parents, since allocation of child heights needs to be based on the full height available in the parent. After this step the Rect Transforms of the layout elements have their new heights.
- 通过调用ILayoutElement组件上的CalculateLayoutInputHorizontal来计算布局元素的最小、首选、灵活宽度。这是从下至上执行的。孩子节点在父亲节点之前计算,这样父亲节点可以在自己的计算中考虑到孩子节点的信息。
- 通过调用ILayoutController组件的SetLayoutHorizontal来计算和设置布局元素的有效宽度,这是自上而下执行的,子节点在父亲节点之后计算,因为子节点宽度的分配需要基于父亲节点可用的全部宽度。在这一步之后,布局元素的Rect Transform就有了新的宽度。
- 通过调用ILayoutElement组件上的CalculateLayoutInputVertical来计算布局元素的最小、首选、灵活高度。这是从下至上执行的。孩子节点在父亲节点之前计算,这样父亲节点可以在自己的计算中考虑到孩子节点的信息。
- 通过调用ILayoutController组件的SetLayoutVertical 来计算和设置布局元素的有效高度,这是自上而下执行的,子节点在父亲节点之后计算,因为子节点宽度的分配需要基于父亲节点可用的全部高度。在这一步之后,布局元素的Rect Transform就有了新的高度。
As can be seen from the above, the auto layout system evaluates widths first and then evaluates heights afterwards. Thus, calculated heights may depend on widths, but calculated widths can never depend on heights.
就像上面看到的一样,自动布局系统先评估宽度再评估高度。因此,计算高度可能基于宽度,但是计算宽度不能基于高度。
Triggering Layout Rebuild
触发布局重建
When a property on a component changes which can cause the current layout to no longer be valid, a layout recalculation is needed. This can be triggered using the call:
当组件上的某个属性发生变化,可能导致当前布局不再有效时,需要重新计算布局。 这可以通过调用下面的函数触发:
LayoutRebuilder.MarkLayoutForRebuild (transform as RectTransform);
The rebuild will not happen immediately, but at the end of the current frame, just before rendering happens. The reason it is not immediate is that this would cause layouts to be potentially rebuild many times during the same frame, which would be bad for performance.
重建不会立即发生,而是在当前帧结束时,即将发生渲染之前。 它不是直接重建的原因是这会导致布局在同一帧期间可能重建多次,这会对性能不利。
Guidelines for when a rebuild should be triggered:
应该触发重建的准则:
- In setters for properties that can change the layout.
- In these callbacks:
- OnEnable
- OnDisable
- OnRectTransformDimensionsChange
- OnValidate (only needed in the editor, not at runtime)
- OnDidApplyAnimationProperties
- 在可以改变布局的属性的setter中
- 在这些回调中:
- OnEnable
- OnDisable
- OnRectTransformDimensionsChange //尺寸变了
- OnValidate (only needed in the editor, not at runtime 只在编辑器需要,运行时不需要)
- OnDidApplyAnimationProperties