The Spark Group and Spark SkinnableContainer containers

The Spark Group and Spark SkinnableContainer containers take as children any components that implement the IVisualElement interface. Use these containers when you want to manage visual children, both visual components and graphical components.

The main differences between the Group and SkinnableContainer containers are:
  • SkinnableContainer can be skinned. The Group container is designed for simplicity and minimal overhead, and cannot be skinned.

  • Group can be a child of the Scroller control to support scroll bars. Create a skin for the SkinnableContainer to add scroll bars.

One of the uses of the Group container is to import graphic elements from Adobe design tools, such as Adobe Illustrator. For example, if you use a design tool to create graphics imported into Flex, the graphics are often represented using FXG statements in a Group container. For more information, see FXG and MXML graphics.

The default layout class of the Group and SkinnableContainer container is BasicLayout. The following example shows a Group container with a horizontal layout and one with a vertical layout:

Box container with a horizontal layout and with a vertical layout

For complete reference information, see the ActionScript 3.0 Reference for the Adobe Flash Platform.

Creating a Spark Group container

You use the <s:Group> tag to define a Group container. Specify an id value if you intend to refer to a component elsewhere in your MXML, either in another tag or in an ActionScript block.

The following example shows a Group container with four Button controls as its children:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerSimple.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:Button label="Button 1" 
            left="10" top="13" bottom="10"/>
        <s:Button label="Button 2"
            left="110" top="13" bottom="10"/>
        <s:Button label="Button 3"
            left="210" top="13" bottom="10"/>
        <s:Button label="Button 4"
            left="310" top="13" bottom="10" right="10"/>
    </s:Group>
</s:Application>

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

In this example, the Group container uses its default layout specified by the BasicLayout class, which means it uses absolute layout. The four button controls then use constraints to set their positions in the container. For more information on constraints, see Using constraints to control component layout.

You can add a graphic element to the container to define a background for the buttons, as the following example shows:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkGroupContainerRect.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:Rect x="0" y="0" 
            radiusX="4" radiusY="4" 
            height="100%" width="100%">
            <s:stroke>
                <s:LinearGradientStroke weight="1" scaleMode="normal"/>
            </s:stroke>
            <s:fill>
                <s:LinearGradient>
                    <s:entries>
                        <mx:GradientEntry color="0x999999"/>
                    </s:entries>
                </s:LinearGradient>
            </s:fill>
        </s:Rect>        
        <s:Button label="Button 1" 
            left="10" top="13" bottom="10"/>
        <s:Button label="Button 2"
            left="110" top="13" bottom="10"/>
        <s:Button label="Button 3"
            left="210" top="13" bottom="10"/>
        <s:Button label="Button 4"
            left="310" top="13" right="10" bottom="10"/>
    </s:Group>
</s:Application>

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

In this example, you add an instance of the Rect class, a subclass of GraphicElement, that defines a gray background and one pixel border around the container. In this example the Rect is located a coordinates 0,0 in the Group container, and sized to fill the entire container.

Creating a Spark SkinnableContainer container

You use the <s:SkinnableContainer> tag to define a SkinnableContainer container. Specify an id value if you intend to refer to a component elsewhere in your MXML, either in another tag or in an ActionScript block.

The following example shows a SkinnableContainer container with four Button controls as its children:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkContainerSimple.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/>
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3"/>
        <s:Button label="Button 4"/>
    </s:SkinnableContainer> 
</s:Application>

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

The default layout class of the SkinnableContainer class is BasicLayout. In this example, the SkinnableContainer uses the HorizontalLayout class to arrange the buttons in a single row.

If the SkinnableContainer uses BasicLayout, you can use a Rect component as a child of the container to add a background color and border. For an example, see Creating a Spark Group container.

However, the SkinnableContainer class lets you apply a skin to define the visual characteristics of the container. For example, the following skin defines a gray background and a one pixel border for the container:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\mySkins\MyBorderSkin.mxml -->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    alpha.disabled="0.5">

    <fx:Metadata>
        [HostComponent("spark.components.SkinnableContainer")]
    </fx:Metadata> 
    
    <!-- Define the skin states. -->
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>
    
    <!-- Define a Rect to fill the area of the skin. -->
    <s:Rect x="0" y="0"
        radiusX="4" radiusY="4"
        height="100%" width="100%">
        <s:stroke>
            <s:LinearGradientStroke weight="1"/>
        </s:stroke>
        <s:fill>
            <s:LinearGradient>
                <s:entries>
                   <mx:GradientEntry color="0x999999"/>
                </s:entries>
            </s:LinearGradient>
        </s:fill>            
    </s:Rect>

    <!-- Define the content area of the container. -->
    <s:Group id="contentGroup"
        left="5" right="5" top="5" bottom="5">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    </s:Group>        
</s:Skin>

All SkinnableContainer skins must implement the view states defined by the SkinnableContainer. Because the SkinnableContainer class supports the normal and disabled view states, the skin must also support them.

The Rect component adds the border and gray background to the skin.

All the container’s children are added to the contentGroup skin part of the skin. In this example, the contentGroup container is a Group container with a vertical layout. Setting the layout property of the SkinnableContainer overrides the layout specified in the skin.

The advantage to defining a skin for the SkinnableContainer, rather than adding the visual elements in the SkinnableContainer definition, is that the skin is reusable. For example, you typically define a consistent look for all SkinnableContainer containers in an application. By encapsulating that look in a reusable skin class, you can apply it to all containers in your application.

Use the skinClass property to apply the skin to the SkinnableContainer, as the following example shows:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkContainerSkin.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
        skinClass="mySkins.MyBorderSkin">
        <s:layout>
            <s:HorizontalLayout gap="10"/> 
        </s:layout>
        <s:Button label="Button 1"/>
        <s:Button label="Button 2"/>
        <s:Button label="Button 3"/>
        <s:Button label="Button 4"/>
    </s:SkinnableContainer>
</s:Application>

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

For more information on skinning, see Spark Skinning.