You can manage a child component's size and position simultaneously by using constraint-based layout, or by using constraint rows and columns. Constraint-based layout lets you anchor the sides or center of a component to positions relative to the viewable region of the component's container. The viewable region is the part of the component that is being displayed, and it can contain child controls, text, images, or other contents.
Constraint rows and columns let you subdivide a container into vertical and horizontal constraint regions to control the size and positioning of child components with respect to each other and within the parent container.
You can use constraint-based layout to determine the position and size of the immediate children of any container that supports absolute positioning. With constraint-based layout you can do the following:
You can specify a constraint-based layout for any Flex framework component (that is, any component that extends the UIComponent class). The following rules specify how to position and size components by using constraint-based layout:
The top, bottom, left, and right styles specify the distances between the component sides and the corresponding container sides.
The baseline constraint specifies the distance between the baseline position of a component and the upper edge of its parent container. Every component calculates its baseline position as the y-coordinate of the baseline of the first line of text of the component. The baseline of a UIComponent object that does not contain any text is calculated as if the UIComponent object contained a UITextField object that uses the component's styles, and the top of the UITextField object coincides with the component's top.
The horizontalCenter and verticalCenter styles specify distance between the component's center point and the container's center, in the specified direction; a negative number moves the component left or up from the center.
The following example anchors the Form control's left and right sides 20 pixels from its container's sides:
<mx:Form id="myForm" left="20" right="20"/>
Precedence rules for constraint-based components
Example: Using constraint-based layout for a form
The following example code shows how you can use constraint-based layout for a form. In this example, the Form control uses a constraint-based layout to position its top just inside the canvas padding. The form left and right edges are 20 pixels from the Canvas container's left and right edges. The HBox that contains the buttons uses a constraint-based layout to place itself 20 pixels from the Canvas right edge and 10 pixels from the Canvas bottom edge.
If you change the size of your browser, stand-alone Flash Player, or AIR application, you can see the effects of dynamically resizing the Application container on the Form layout. The form and the buttons overlap as the application grows smaller, for example. In general, you should include the buttons in the last FormItem of the form. However, in the following example, the buttons are separated in an HBox container to better show the effects of resizing:
<?xml version="1.0"?>
<!-- components\ConstraintLayout.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<!-- Use a Canvas container in the Application to prevent
unnecessary scroll bars on the Application. -->
<mx:Canvas width="100%" height="100%">
<!-- Anchor the top of the form at the top of the canvas.
Anchor the form sides 20 pixels from the canvas sides. -->
<mx:Form id="myForm"
backgroundColor="#DDDDDD"
top="0"
left="20"
right="20">
<mx:FormItem label="Product:" width="100%">
<!-- Specify a fixed width to keep the ComboBox control from
resizing as you change the application size. -->
<mx:ComboBox width="200"/>
</mx:FormItem>
<mx:FormItem label="User" width="100%">
<mx:ComboBox width="200"/>
</mx:FormItem>
<mx:FormItem label="Date">
<mx:DateField/>
</mx:FormItem>
<mx:FormItem width="100%"
direction="horizontal"
label="Hours:">
<mx:TextInput width="75"/>
<mx:Label text="Minutes" width="48"/>
<mx:TextInput width="75"/>
</mx:FormItem>
</mx:Form>
<!-- Anchor the box with the buttons 20 pixels from the canvas
right edge and 10 pixels from the bottom. -->
<mx:HBox id="okCancelBox"
right="20"
bottom="10">
<mx:Button label="OK"/>
<mx:Button label="Cancel"/>
</mx:HBox>
</mx:Canvas>
</mx:Application>
The executing SWF file for the previous example is shown below:
You can subdivide a container that supports absolute positioning into vertical and horizontal constraint regions to control the size and positioning of child components with respect to each other, or with respect to the parent container.
You define the horizontal and vertical constraint regions of a container by using the constraintRows and constraintColumns properties. These properties contain Arrays of constraint objects that partition the container horizontally (ConstraintColumn objects) and vertically (ConstraintRow objects). ConstraintRow objects are laid out in the order they are defined, from top to bottom in their container; ConstraintColumn objects are laid out from left to right in the order they are defined.
The following example shows a Canvas container partitioned into two vertical regions and two horizontal regions. The first constraint column occupies 212 pixels from the leftmost edge of the Canvas. The second constraint column occupies 100% of the remaining Canvas width. The rows in this example occupy 80% and 20% of the Canvas container's height from top to bottom, respectively.
<?xml version="1.0"?>
<!-- constraints\BasicRowColumn.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas>
<mx:constraintColumns>
<mx:ConstraintColumn id="col1" width="212"/>
<mx:ConstraintColumn id="col2" width="100%"/>
</mx:constraintColumns>
<mx:constraintRows>
<mx:ConstraintRow id="row1" height="80%"/>
<mx:ConstraintRow id="row2" height="20%"/>
</mx:constraintRows>
<!-- Position child components based on
the constraint columns and rows. -->
</mx:Canvas>
</mx:Application>
Constraint rows and columns do not have to occupy 100% of the available area in a container. The following example shows a single constraint column that occupies 20% of the Canvas width; 80% of the container is unallocated:
<?xml version="1.0"?>
<!-- constraints\BasicColumn_20Percent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas>
<mx:constraintColumns>
<mx:ConstraintColumn id="col1" width="20%"/>
</mx:constraintColumns>
</mx:Canvas>
<!-- Position child components based on
the constraint column. -->
</mx:Application>
Creating constraint rows and columns
Constraint columns and rows have three sizing options: fixed, percent, and content. These options dictate the amount of space that the constraint region occupies in the container. As child components are added to or removed from the parent container, the space allocated to each ConstraintColumn and ConstraintRow instance is computed according to its sizing option.
<mx:ConstraintColumn id="col1" width="100"/>
As the parent container grows or shrinks, the ConstraintColumn instance remains 100 pixels wide.
In the following example, you set the with of a ConstraintColumn instance to 80%:
<mx:ConstraintColumn id="col1" width="80%"/>
As the parent container grows or shrinks, the ConstraintColumn always takes up 80% of the available width.
A best practice in specifying percent constraints is to ensure that the sum of all percent constraints is less than or equal to 100%. However, if the total value of percent specifications is greater than 100%, the actual allocated percentages are calculated so that the proportional values for all constraints total 100%. For example, if the percentages for two constraint objects are specified as 100% and 50%, the values are adjusted to 66.6% and 33.3% (two-thirds for the first value and one-third for the second).
In the following example, you specify content size by omitting any explicit width setting:
<mx:ConstraintColumn id="col1"/>
The width of this ConstraintColumn is determined by the width of its largest child. When children span multiple content sized constraint rows or constraint columns, Flex divides the space consumed by the children among the rows and columns.
For the ConstraintColumn class, you can also use the maxWidth and minWidth properties to limit the width of the column. For the ConstraintRow class, you can use the maxHeight and minHeight properties to limit the height of the row. Minimum and maximum sizes for constraint columns and rows limit how much the constraint regions grow or shrink when you resize their parent containers. If the parent container with a constraint region shrinks to less than the minimum size for that region when you resize the container, scrollbars appear to show clipped content.
Positioning child components based on constraint rows and constraint columns
Anchor a child component to a constraint row or constraint column by prepending the constraint region's ID to any of the child's constraint parameters. For example, if the ID of a ConstraintColumn is "col1", you can specify a set of child constraints as left="col1:10", right="col1:30", horizontalCenter="col1:0".
If you do not qualify constraint parameters (left, right, top, and bottom) a constraint region ID, the component is constrained relative to the edges of its parent container. Components can occupy a single constraint region (row or column) or can span multiple regions.
The following example uses constraint rows and constraint columns to position three Button controls in a Canvas container:
<?xml version="1.0"?>
<!-- constraints\ConstrainButtons.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas id="myCanvas" backgroundColor="0x6699FF">
<mx:constraintColumns>
<mx:ConstraintColumn id="col1" width="100"/>
<mx:ConstraintColumn id="col2" width="100"/>
</mx:constraintColumns>
<mx:constraintRows>
<mx:ConstraintRow id="row1" height="100"/>
<mx:ConstraintRow id="row2" height="100"/>
</mx:constraintRows>
<mx:Button label="Button 1"
top="row1:10" bottom="row1:10"
left="10"/>
<mx:Button label="Button 2"
left="col2:10" right="col2:10"/>
<mx:Button label="Button 3"
top="row2:10" bottom="row2:10"
left="col1:10" right="10"/>
</mx:Canvas>
<mx:Label text="canvas width:{myCanvas.width}"/>
<mx:Label text="canvas height:{myCanvas.height}"/>
</mx:Application>
The executing SWF file for the previous example is shown below:
The next example defines the constraint rows and columns by using percentages. As you resize the application, the Button controls resize accordingly.
<?xml version="1.0"?>
<!-- constraints\ConstrainButtonsPercent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas id="myCanvas"
backgroundColor="0x6699FF"
width="100%" height="100%">
<mx:constraintColumns>
<mx:ConstraintColumn id="col1" width="30%"/>
<mx:ConstraintColumn id="col2" width="40%"/>
<mx:ConstraintColumn id="col3" width="30%"/>
</mx:constraintColumns>
<mx:constraintRows>
<mx:ConstraintRow id="row1" height="35%"/>
<mx:ConstraintRow id="row2" height="55%"/>
</mx:constraintRows>
<mx:Button label="Button 1"
top="row1:10" bottom="row2:10"
left="10"/>
<mx:Button label="Button 2"
left="col2:10" right="col3:10"/>
<mx:Button label="Button 3"
top="row2:10" bottom="row2:10"
left="col3:10" right="col3:10"/>
</mx:Canvas>
<mx:Label text="canvas width:{myCanvas.width}"/>
<mx:Label text="canvas height:{myCanvas.height}"/>
</mx:Application>
The executing SWF file for the previous example is shown below:
While you may specify any combination of qualified and unqualified constraints, some constraint properties may be overridden. The priority of sizing and positioning constraints are as follows:
The following table defines the behavior of constrained components when they are contained in a single constraint region. Edge 1 is the first specified edge constraint for a child component (left, right, top, or bottom). Edge 2 is the second specified edge constraint of a pair (left and right, top and bottom). Size is an explicit size for a child component (width, height). Center is the positioning constraint to center the child object (horizontalCenter or verticalCenter).
|
Constraint Parameters |
Behavior |
||||
|---|---|---|---|---|---|
|
Edge 1 |
Edge 2 |
Size |
Center |
Size |
Position |
|
x |
|
|
|
Default component size |
Relative to specified edge constraint |
|
x |
x |
|
|
Calculated from specified edge constraints |
Relative to specified edge constraints |
|
x |
x |
x |
|
Determined from specified edge constraints. Explicit size is overridden |
Relative to specified edge constraints |
|
x |
|
x |
|
Specified size |
Relative to specified edge |
|
x |
|
|
x |
Default component size |
Centered in constraint region; edge constraint is ignored |
|
x |
x |
|
x |
Calculated from edge constraints |
Centered in constraint region |
|
x |
|
x |
x |
Explicit size |
Centered in constraint region; single edge constraint is ignored |
|
|
|
|
x |
Default size of component |
Centered in constraint region |