By default, Flex automatically positions all components, except for the children of a Canvas container. If you have a Canvas container, or an Application or Panel container with the layout property set to absolute, you specify absolute positions for its children, or use constraint-based layout. You can use automatic positions and absolute positioning by using x and y properties. For information on using constraint-based layout, which can control both positioning and sizing, see Using constraints to control component layout.
For most containers, Flex automatically positions the container children according to the container's layout rules, such as the layout direction, the container padding, and the gaps between children of that container.
For containers that use automatic positioning, setting the x or y property directly or calling move() has no effect, or only a temporary effect, because the layout calculations set the x position to the calculation result, not the specified value. You can, however, specify absolute positions for the children of these containers under some circumstances; for more information, see Disabling automatic positioning temporarily.
You can control aspects of the layout by specifying container properties; for details on the properties, see the property descriptions for the container in the Adobe Flex Language Reference. You also control the layout by controlling component sizes and by using techniques such as adding spacers.
Using the Spacer control to control layout
Flex includes a Spacer control that helps you lay out children within a parent container. The Spacer control is invisible, but it does allocate space within its parent.
In the following example, you use a percentage-based Spacer control to push the Button control to the right so that it is aligned with the right edge of the HBox container:
<?xml version="1.0"?>
<!-- components\SpacerHBox.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Embed(source="assets/flexlogo.jpg")]
[Bindable]
public var imgCls:Class;
]]>
</mx:Script>
<mx:HBox width="400">
<mx:Image source="{imgCls}"/>
<mx:Label text="Company XYZ"/>
<mx:Spacer width="100%"/>
<mx:Button label="Close"/>
</mx:HBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
In this example, the Spacer control is the only percentage-based component in the HBox container. Flex sizes the Spacer control to occupy all available space in the HBox container that is not required for other components. By expanding the Spacer control, Flex pushes the Button control to the right edge of the container.
You can use all sizing and positioning properties with the Spacer control, such as width, height, maxWidth, maxHeight, minWidth, and minHeight.
Disabling automatic positioning temporarily
You can use effects, such as the Move and Zoom effects, to modify the size or position of a child in response to a user action. For example, you might define a child so that when the user selects it, the child moves to the top of the container and doubles in size. These effects modify the x and y properties of the child as part of the effect. Similarly, you might want to change the position of a control by changing its x or y coordinate value, for example, in response to a button click.
Containers that use automatic positioning ignore the values of the x and y properties of their children during a layout update. Therefore, the layout update cancels any modifications to the x and y properties performed by the effect, and the child does not remain in its new location.
You can prevent Flex from performing automatic positioning updates that conflict with the requested action of your application by setting the autoLayout property of a container to false. Setting this property to false prevents Flex from laying out the container's contents when a child moves or resizes. Flex defines the autoLayout property in the Container class, and all containers inherit it; its default value is true, which enables Flex to update layouts.
Even when you set the autoLayout property of a container to false, Flex updates the layout when you add or remove a child. Application initialization, deferred instantiation, and the <mx:Repeater> tag add or remove children, so layout updates always occur during these processes, regardless of the value of the autoLayout property. Therefore, during container initialization, Flex defines the initial layout of the container children regardless of the value of the autoLayout property.
The following example disables layout updates for a VBox container:
<?xml version="1.0"?>
<!-- components\DisableVBoxLayout.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:VBox autoLayout="false"
width="200"
height="200"
>
<mx:Button id="b1"
label="Button 1"
/>
<mx:Button id="b2"
label="Button 2"
click="b2.x += 10;"
/>
<mx:Button id="b3"
label="Button 3"
creationComplete="b3.x = 100; b3.y = 75;"
/>
</mx:VBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
In this example, Flex initially lays out all three Button controls according to the rules of the VBox container. The creationComplete event listener for the third button is dispatched after the VBox control has laid out its children, but before Flex displays the buttons. Therefore, when the third button appears, it is at the x and y positions specified by the creationComplete listener. After the buttons appear, Flex shifts the second button 10 pixels to the right each time a user clicks it.
Setting the autoLayout property of a container to false prohibits Flex from updating a container's layout after a child moves or resizes, so you should set it to false only when absolutely necessary. You should always test your application with the autoLayout property set to the default value of true, and set it to false only as necessary for the specific container and specific actions of the children in that container.
For more information on effects, see Using Behaviors.
Preventing layout of hidden controls
By default, Flex lays out and reserves space for all components, including hidden components, but it does not display the hidden controls. You see blank spots where the hidden controls will appear when you make them visible. In place of the hidden controls, you see their container's background. However, if the container is any of the following components, you can prevent Flex from considering the child component when it lays out the container's other children by setting the child component's includeInLayout property of the component to false:
When a component's includeInLayout property is false, Flex does not include it in the layout calculations for other components, but still lays it out. In other words, Flex does not reserve space for the component, but still draws it. As a result, the component can appear underneath the components that follow it in the layout order. To prevent Flex from drawing the component, you must also set its visible property to false.
The following example shows the effects of the includeInLayout and visible properties. It lets you toggle each of these properties independently on the middle of three Panel controls in a VBox control:
<?xml version="1.0"?>
<!-- components\HiddenBoxLayout.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:VBox>
<mx:Panel id="p1"
title="Panel 1"
backgroundColor="#FF0000"/>
<mx:Panel id="p2"
title="Panel 2"
backgroundColor="#00FF00"/>
<mx:Panel id="p3"
title="Panel 3"
backgroundColor="#0000FF"/>
</mx:VBox>
<mx:HBox>
<mx:Button label="Toggle Panel 2 Visible"
click="{p2.visible=!p2.visible;}"/>
<mx:Button label="Toggle Panel 2 in Layout"
click="{p2.includeInLayout=!p2.includeInLayout;}"/>
</mx:HBox>
</mx:Application>
The executing SWF file for the previous example is shown below:
Run this application and click the buttons to see the results of different combinations of visible and includeInLayout properties. The example shows the following behaviors:
Three containers support absolute positioning:
With absolute positioning, you specify the child control position by using its x and y properties, or you specify a constraint-based layout; otherwise, Flex places the child at position 0,0 of the parent container. When you specify the x and y coordinates, Flex repositions the controls only when you change the property values. The following example uses absolute positioning to place a VBox control inside a Canvas control:
<?xml version="1.0"?>
<!-- components\CanvasLayout.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[#FFFFFF, #FFFFFF]">
<mx:Canvas
width="100" height="100"
backgroundColor="#999999">
<mx:VBox id="b1"
width="80" height="80"
x="20" y="20"
backgroundColor="#A9C0E7">
</mx:VBox>
</mx:Canvas>
</mx:Application>
The executing SWF file for the previous example is shown below:
This example produces the following image:
When you use absolute positioning, you have full control over the locations of the container's children. This lets you overlap components. The following example adds a second VBox to the previous example so that it partially overlaps the initial box.
<?xml version="1.0"?>
<!-- components\CanvasLayoutOverlap.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[#FFFFFF, #FFFFFF]">
<mx:Canvas
width="100" height="100"
backgroundColor="#999999">
<mx:VBox id="b1"
width="80" height="80"
x="20" y="20"
backgroundColor="#A9C0E7">
</mx:VBox>
<mx:VBox id="b2"
width="50" height="50"
x="0" y="50"
backgroundColor="#FF0000">
</mx:VBox>
</mx:Canvas>
</mx:Application>
The executing SWF file for the previous example is shown below:
This example produces the following image: