About sizing and positioning

Component layout has two parts: component sizing and component positioning. Flex controls the layout of components by using a set of rules. These layout rules are a combination of sizing rules for individual components, and sizing and positioning rules for containers.

Because Flex defines default layout rules, you often do not have to set the size or position of components. Instead, you can concentrate on building the logic of your application and let Flex control the layout.

While Flex has default layout rules, you can use the component’s properties and methods to customize the layout. For example, all components have several properties, including height and width, for specifying the component’s size in absolute or container-relative terms.

Each container also has properties and styles that you can use to configure aspects of layout. You can also use different positioning techniques for laying out components in a container. For example, some containers support absolute x- and y-coordinate–based positioning.

About layout with Spark and MX containers

While the sizing and layout rules for Spark and MX containers are almost identical, there are a few differences between the two types of containers:

  • Spark containers let you specify the layout class assigned to the container, such as BasicLayout, HorizontalLayout, VerticalLayout, and TileLayout.

    MX containers have a predefined layout built in to the class. Therefore, the MX VBox container always lays out its children in a vertical column, and the MX Tile container always lays out its children in rows and columns. The only exceptions to this rule are the MX Application and MX Panel containers. These containers let you switch among absolute, vertical, and horizontal layout.

  • Spark containers use properties on the layout class to control the layout of the container. For example, use the TileLayout.verticalGap and TileLayout.horizontalGap properties to set the gaps between children of a Spark container that uses the TileLayout class.

    MX containers use properties and styles of the container class. Therefore, to set the gaps for a MX container, set the verticalGap and horizontalGap styles on the container.

About the Layout Manager

The Layout Manager controls layout in Flex. The manager uses the following three-stage process to determine the size and position of each component in an application:

Stage 1 - Commitment pass
Determines the property settings of the application’s components. This pass allows components whose contents depend on property settings to configure themselves before Flex determines their sizes and positions.

During the commitment pass, the Layout Manager causes each component to run its commitProperties() method, which determines the property values.

Stage 2 - Measurement pass
Calculates the default size of every component in the application. This pass starts from the most deeply nested components and works out toward the application container.

The measurement pass determines the measured, or default, size of each component. The default size of each container is based on the default or explicit (if specified) sizes of its children. For example, an SkinnableContainer that uses the HorizontalLayout class has a default width equal to the sum of the default or explicit widths of all its children, plus the thickness of the borders, any padding, and the gaps between the children.

During the measurement pass, the Layout Manager causes each component to call its measure() method to determine the component’s default size. All sizing properties are calculated before Flex applies any transform to the component, such as a rotation, skew, or other transform.

Stage 3 - Layout pass
Lays out your application, including moving and resizing any components. This pass starts from the outermost container and works in toward the innermost component. The layout pass determines the actual size and placement of each component. It also does any programmatic drawing, such as calls to the lineTo() or drawRect() methods.

The Layout Manager causes each component to run its updateDisplayList() method to lay out the component’s children; for this reason, this pass is also referred to as the update pass.

When lay out occurs

Flex lays out components when your application initializes. Flex also performs a layout pass when the application or a user does something that affects the sizes or positions of visual elements, including the following:

  • The application changes properties that specify sizing or positioning, such as x, y, width, height, scaleX, scaleY, rotationX, rotationY, and the transform matrix.

  • A change affects the calculated width or height of a component, such as when the label text for a Button control changes, or the user resizes a component.

  • A child is added or removed from a container, a child is resized, or a child is moved. For example, if your application can change the size of a component, Flex updates the layout of the container to reposition its children, based on the new size of the child.

  • A property or style that requires measurement and drawing, such as the fontFamily, changes.

Manually forcing layout

Sometimes, you might have to programmatically cause Flex to update application layout. Situations where you must force a layout include the following:

  • When printing multiple page data grids by using the PrintDataGrid class.

  • Before playing an effect, if the start values have just been set on the target.

  • When capturing bitmap data after making property changes.

To force a layout, call the validateNow() method of the component to lay out. This method causes Flex to validate and update the properties, sizes, and layout of the object and all its children, and to redraw them, if necessary. Because this method is computation-intensive, be careful to call it only when it is necessary.

About component sizing

Flex provides several ways for you to control the size of controls and containers:

Default sizing
Flex automatically determines the sizes of controls and containers.

Explicit sizing
You set the height and width properties of the component to absolute values.

Percentage-based sizing
You specify the component size as a percentage of its parent container’s size.

Constraint-based layout
You control size and position by anchoring component’s sides to locations in their container.

For details on controlling component sizes, see Sizing components.

About component positioning

Flex provides two mechanisms for positioning controls:

Automatic positioning
Flex automatically positions a container’s children according to a set of container- and component-specific rules. Most containers use automatic positioning. Automatic positioning is sometimes referred to as automatic layout. One of the differences between Spark and MX containers is that the layout algorithm for MX containers is fixed, but for Spark containers it is selectable by changing the container’s layout property.

Absolute positioning
You specify each child’s x and y properties, or use a constraint-based layout that specifies the distance between one or more of the container’s sides and the child’s sides, baseline, or center. Absolute positioning is sometimes referred to as absolute layout. Spark containers with a layout of BasicLayout and the MX Canvas container use absolute layout. You can also choose absolute layout for the MX Application and Panel containers.

For details on controlling the positions of controls, see Positioning components.

About basic layout properties and methods

While Flex provides many properties that you can use to control and monitor component layout, there are a few that you use frequently. The following figure shows these properties and methods:

This figure shows how Flex lays out a component in its parent container. The x, y, height, and width properties of the component determine its size before any skins or transformations are applied to it. These are properties that you can set when defining your application.

After Flex applies any skins or transformations to the component, Flex uses the rectangular area, called the bounding box, to position the component in its parent container. The bounding box defines the rectangular are taken up by the component in its parent container. In the absence of any skin or transformation, the size of the bounding box is the same as the height and width of the component.

A graphical component, such as Ellipse and Rect, can define a stroke for their border. If the component defines a stroke, the center of the stroke runs along the outer edge of the component. For example, if you define a two-pixels wide border, the border appears in the area one-pixel outside the component to one-pixel inside the component. The border has to fit completely within the bounding box. Therefore, the upper-left corner of the component might be offset from the edge of the bounding box to accommodate the border.

The following table describes the basic component layout properties and methods:

Property or method

Description

x, y

The x and y coordinate of the upper-left corner of the component in the parent container. You can set these properties for the children of a container that use absolute layout. Otherwise, Flex calculates these values for you.

height, width

The height and width of the component. You can set these properties as a pixel value or as a percent of the size of the parent container. Otherwise, Flex calculates these values for you.

top, bottom, left, right

The distances between the sides of the component and sides of the parent container. Use these properties when performing constraint-based layout. Only containers that use absolute layout support constraint-based layout. For more information, see Using constraints to control component layout.

getLayoutBoundsX(), getLayoutBoundsY()

The x and y coordinates of the bounding box of the component in the parent container after any skins and transformations have been applied to the component.

getlayoutBoundsHeight()getLayoutBoundsWidth()

The height hand width of the bounding box of the component in the parent container after any skins and transformations have been applied to the component. \

Basic layout rules and considerations

Flex performs layout according to the following basic rules. If you remember these rules, you should be able to easily understand the details of Flex layout. These rules help you determine why Flex lays out your application as it does and to determine how to modify your application appearance.

For a detailed description of how Flex sizes components, see Determining and controlling component sizes. For detailed information on component positioning, see Positioning components.

  • Flex first determines all components’ measured (default) or explicitly set sizes up, from the innermost child components to the outermost (Application) component. This is done in the measurement pass.

  • After the measurement pass, Flex determines all percentage-based sizes and constraints applied to the components. Flex then lays out components down, from the outermost container to the innermost components. This is done in the layout pass.

  • Sizes that you set to a pixel value are mandatory and fixed, and override any maximum or minimum size specifications that you set for the component.

  • The default sizes determined in the measurement pass specify the sizes of components that do not have explicit or percentage-based sizes (or use constraint-based layout), and are fixed.

  • Percentage-based size specifications are advisory. The layout algorithms satisfy the request if possible, and use the percentage values to determine proportional sizes, but the actual sizes can be less than the requested sizes. Percentage-based sizes are always within the component’s maximum and minimum sizes, and, subject to those bounds, don’t cause a container’s children to exceed the container size.

Component layout patterns

Flex uses different patterns to lay out different containers and their children. These patterns generally fit in the type categories listed in the following table. The table describes the general layout behavior for each type, how the default size of the container is determined, and how Flex sizes percentage-based children.

Pattern

Container type

Default layout behavior

Absolute positioning

Spark container using BasicLayout

MX Canvas container or Application or Panel container with layout="absolute"

General layout: Children of the container do not interact. That is, children can overlap and the position of one child does not affect the position of any other child. You specify the child positions explicitly or use constraints to anchor the sides, baselines, or centers of the children relative to the parent container.

Default sizing: The measurement pass finds the child with the lowest bottom edge and the child with the rightmost edge, and uses these values to determine the container size.

Percentage-based children: Sizing uses different rules depending on whether you use constraint-based layout or x- and y- coordinate positioning. See Flex component sizing techniques.

Containers that arrange children linearly

Spark containers using HorizontalLayout or VerticalLayout

MX Box, DividedBox, Form, Panel, TitleWindow containers

General layout: All children of the container are arranged in a single row or column. Each child’s height and width can differ from all other children’s heights or widths.

Default sizing: The container fits the default or explicit sizes of all children and all gaps, borders, and padding.

Percentage-based children: If children with percentage-based sizing request more than the available space, the actual sizes are set to fit in the space, proportionate to the requested percentages.

Grid

MX Grid container

General layout: A container with a vertical layout of rows. Each row is a container with a horizontal layout of child controls, where all items are constrained to align with each other. The heights of all the cells in a single row are the same, but each row can have a different height. The widths of all cells in a single column are the same, but each column can have a different width. You can define a different number of cells for each row or each column of the Grid container, and individual cells can span columns or rows.

Default sizing: The grid fits the individual rows and children at their default sizes.

Percentage-based children: If children use percentage-based sizing, the sizing rules fit the children GridItem components within their rows, and GridRow components within the grid size according to linear container sizing rules.

Tile

Spark container using TileLayout

MX Tile container

General layout: The container is a grid of equal-sized cells. The cells can be in row-first or column-first order.

For MX, if you do not specify explicit or percentage-based dimensions, the container has as close as possible to an equal number of rows and columns, with the direction property determining the orientation with the larger number of items, if necessary.

For Spark, if you do not specify explicit or percentage-based dimensions, the container arranges the rows and columns so that the container has an equal height and width. The orientation property determining the orientation with the larger number of items, if necessary.

Default sizing: If you do not specify tileWidth and tileHeight properties (MX Tile container) or columnWidth and rowHeight (Spark Tile layout), the container uses the measured or explicit size of the largest child cell for the size of each child cell.

Percentage-based children: The percentage-based sizes of a child component specify a percentage of the individual cell, not of the Tile container.

Navigators

MX ViewStack, Accordion, and TabNavigator containers

General layout: The container displays one child at a time.

Default sizing: The container size is determined by the measured or explicit dimensions of the initially selected child, and thereafter, all children are forced to be that initial size. If you set the resizeToChild property to true the container resizes to accommodate the measured or explicit size of each child, as that child appears.

Percentage-based children: As a general rule, you either use 100% for both height and width, which causes the children to fill the navigator bounds, or do not use percentage-based sizing.