About Spark layouts

All Spark containers define a default layout, but let you switch the layout to suit your application requirements. To switch layout, assign a layout class to the layout property of the container.

Flex ships with several layout classes that you can use with the Spark containers. Additionally, you can define custom layout classes. The layout classes are defined in the spark.layouts package, and include the following classes:
  • BasicLayout Uses absolute positioning. You explicitly position all container children, or use constraints to position them.

  • HorizontalLayout Lays out children in a single horizontal row. The height of the row is fixed to the same height for all children and is typically the height of the tallest child. The width of each child is either fixed to the same value for all children, or each child can calculate its own width. By default, each child calculates its own width.

  • TileLayout Lays out children in one or more vertical columns or horizontal rows, starting new rows or columns as necessary. The orientation property determines the layout direction. The valid values for the orientation property are columns for a column layout and rows (default) for a row layout.

    All cells of the tile layout have the same size, which is the height of the tallest child and the width of the widest child.

  • VerticalLayout Lays out children in a single vertical column. The width of the column is fixed to the same width for all children and is typically the width of the widest child. The height of each child is either fixed to the same value for all children, or each child can calculate its own height. By default, each child calculates its own height.

Setting the layout of a Spark container

By default, the Group container uses the BasicLayout class. The following example uses the layout property of the container to set its layout to the HorizontalLayout class:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerHorizontal.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Group>
        <s:layout>
            <s:HorizontalLayout/>
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3"/>
        <s:Button label="Button 4"/>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

To simplify the use of layouts with the Group container, Flex defines subclasses of Group: HGroup with a horizontal layout, VGroup with a vertical layout, and TileGroup with a tile layout. Therefore, you can rewrite the previous example as shown below:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkHGroupContainer.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:HGroup>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3"/>
        <s:Button label="Button 4"/>
    </s:HGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

Setting the padding and gap of a layout

The Spark layout classes support padding and gap properties. The padding properties define the space between the container boundaries and the children. The gap properties define the space between the children, either horizontally or vertically.

The following example sets the padding to 10 pixels, and the gap to 5 pixels, for the children of a Panel container:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkPanelPadding.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Panel>
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10" paddingRight="10"
                paddingTop="10" paddingBottom="10"
                gap="5"/>
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3"/>
        <s:Button label="Button 4"/>
    </s:Panel>
</s:Application>

The executing SWF file for the previous example is shown below:

Setting the alignment of a layout

The layout containers provide the horizontalAlign and verticalAlign properties for aligning the children of a container. For example, you can use these properties to align children to the top of a container using HorizontalLayout, or to the left side of a container using VerticalLayout.

The horizontalAlign property takes the following values:

  • left Align children to the left side of the container. This is the default value for VerticalLayout.

  • right Align children to the right side of the container.

  • center Align the children to the horizontal center of the container.

  • justify Set the width of all children to be the same width as the container.

  • contentJustify Set the width of all children to be the content width of the container. The content width of the container is the width of the largest child. If all children are smaller than the width of the container, then set the width of all the children to the width of the container.

The verticalAlign property takes the following values:

  • top Align children to the top of the container. This is the default value for VerticalLayout.

  • bottom Align children to the bottom of the container.

  • middle Align children to the vertical middle of the container.

  • justify Set the height of all children to be the same height as the container.

  • contentJustify Set the height of all children to be the content height of the container. The content height of the container is the height of the largest child. If all children are smaller than the height of the container, then set the height of all the children to the height of the container.

The following example overrides the default vertical alignment of top for the HorizontalLayout to align the children of a Group container to the bottom of the container:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkContainerSimpleAlignment.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
     
    <s:SkinnableContainer>
        <s:layout>
            <s:HorizontalLayout verticalAlign="bottom"/>
        </s:layout>
        <s:Button label="Button 1" fontSize="24"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3" fontSize="36"/>
        <s:Button label="Button 4"/>
    </s:SkinnableContainer> 
</s:Application>

The executing SWF file for the previous example is shown below:

The following example overrides the default vertical alignment of top for the HorizontalLayout to use justify. Notice that all buttons have the same height:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkContainerSimpleAlignment.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
     
    <s:SkinnableContainer>
        <s:layout>
            <s:HorizontalLayout verticalAlign="justify"/>
        </s:layout>
        <s:Button label="Button 1" fontSize="24"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3" fontSize="36"/>
        <s:Button label="Button 4"/>
    </s:SkinnableContainer> 
</s:Application>

The executing SWF file for the previous example is shown below:

Setting the row height or column width of a layout

You control the way the container lays out children with different sizes by using the VerticalLayout.variableRowHeight and HorizontalLayout.variableColumnWidth properties. By default, these properties are set to true which lets each child determine its height (VerticalLayout) or width (HorizontalLayout).

In the following example, the Group container holds four buttons. By default, buttons use a 12 point font size. However, two of the buttons in this example define a larger font size. Because the variableRowHeight property is set to true by default, the container sets the height of each button appropriately for its font size:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerVarRowHeightTrue.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Group>
        <s:layout>
            <s:VerticalLayout />
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3" fontSize="36"/>
        <s:Button label="Button 4" fontSize="24"/>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

If your container has many children, setting the variableRowHeight or variableColumnWidth properties to true can affect application performance. The reason is because the container calculates the size of every child as it appears on the screen.

Rather than having each child calculate its size, you can set the variableRowHeight or variableColumnWidth property to false so that each child has the same size.

Note: The following paragraphs describe setting the variableRowHeight property for the VerticalLayout class. This discussion is the same as setting the variableColumnWidth property for the HorizontalLayout class.
If you set the variableRowHeight property to false, the VerticalLayout class uses the following procedure to determine the height of each child:
  1. If specified, use the VerticalLayout.rowHeight property to specify an explicit height of all children. Make sure that the specified height is suitable for all children.

  2. If specified, use the VerticalLayout.typicalLayoutElement property to define the height of all children. This property references a component that Flex uses to define the height of all container children.

  3. Use the preferred width of the first container child as the height of all container children. This technique is useful if the children of the container are all similar.

In the following example, a group container uses the VerticalLayout class to lay out four Button controls. The variableRowHeight property is false so that every button has the same height:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerVarRowHeightFalse.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Group>
        <s:layout>
            <s:VerticalLayout variableRowHeight="false"/> 
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3" fontSize="36"/>
        <s:Button label="Button 4" fontSize="24"/>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

Because you did not specify an explicit value for the VerticalLayout.rowHeight property or the VerticalLayout.typicalLayoutElement property, the VerticalLayout class uses the preferred height of the first button control as the height for all container children. However, because the third button and fourth button controls define a large font size, the text is truncated to the size of the button.

Alternatively, you can set the rowHeight property to a pixel value large enough for all the children, as the following example shows:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerVarRowHeightFalseRowHeight.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Group>
        <s:layout>
            <s:VerticalLayout variableRowHeight="false" 
                rowHeight="40"/> 
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3" fontSize="36"/>
        <s:Button label="Button 4" fontSize="24"/>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

In this example, all buttons are 40 pixels tall.

The following example uses the typicalLayoutElement property to specify to use the third button to determine the height of all container children:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerVarRowHeightFalseTypicalLE.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Group>
        <s:layout>
            <s:VerticalLayout variableRowHeight="false"
                typicalLayoutElement="{b3}"/> 
        </s:layout>
        <s:Button id="b1" label="Button 1"/>
        <s:Button id="b2" label="Button 2"/>
        <s:Button id="b3" label="Button 3" fontSize="36"/>
        <s:Button id="b4" label="Button 4" fontSize="24"/>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

You can use two common strategies for determining the typical item. One option is to use the largest item as the typical item. Another option is to calculate the average size of all items, and use the data item closest to that average size.