Flex 4: DataGroup and ItemRenderers
Today the beta's of Flash Catalyst and Flash Builder became available for download on Adobe Labs. This means that we can now start to play with the new Flex 4 SDK. There has been some controversy lateley about the pro's and cons of Flex namespaces. I was in the pro camp as you can see in this post I made some time ago. But enough about this discussion
If you want to have more information about the new Flex 4 SDK and what has changed you can go to the following articles:
- What's new in Flex 4 SDK beta by Matt Chotin (Flex 4 SDK Product Manager)
- Differences between Flex 3 SDK and Flex 4 SDK beta by Joan Lafferty
- Overview of Flex 4 by Sean More
- Flex 4 & Custom Layouts by Andrew Trice
- What's new in Flash Builder 4 beta by Tim Buntel (Flash Builder Product Manager)
For my first blog post about Flex 4 I want to show you one of the new components, and that's the spark.components.DataGroup component. Why? Because I have been using the old mx.core.Repeater a lot and there is no repeater in the new spark components.
In the old days of Flex 3 you could use the Repeater class when you needed a very specific view for customizing a list of data. It would look something like this:
<mx:Repeater id="myRepeater">
<mx:dataProvider>
<local:Person firstName="Alain" lastName="Hufkens"/>
<local:Person firstName="Hugh" lastName="Hefner"/>
<local:Person firstName="Jimi" lastName="Hendrix"/>
</mx:dataProvider>
<mx:HBox>
<mx:Label text="{myRepeater.currentItem.firstName}"/>
<mx:Label text="{myRepeater.currentItem.lastName}"/>
</mx:HBox>
</mx:Repeater>
</mx:VBox>
This example here is pretty simple, but it gives you a list that displays the persons showing the first and last name. You could extend this with the person's photo or address.
With the new DataGroup component you need a different approach and you need to work with ItemRenderers, something that already existed in the Flex 3 SDK. The next code snippets show you how to do this:
The first example uses the spark.skins.default.DefaultItemRenderer that can be used for very simple lists. By default the list outputs the toString() of an Object or in this example shows the String from the DataProvider.
<s:layout>
<s:VerticalLayout gap="1" />
</s:layout>
<s:dataProvider>
<s:ArrayCollection>
<fx:String>Frog</fx:String>
<fx:String>Cat</fx:String>
<fx:String>Mouse</fx:String>
</s:ArrayCollection>
</s:dataProvider>
</s:DataGroup>
The next example uses the spark.skins.default.DefaultComplexItemRenderer. This ItemRenderer renders different Graphical and complex components. You can have a Component like a Button, DropDownList, ... next to a graphical object like a Rect, Ellipse, ... next to each other.
<s:SolidColor id="fillColor" color="#fff000"/>
</fx:Declarations>
<s:DataGroup itemRenderer="spark.skins.default.DefaultComplexItemRenderer">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:dataProvider>
<s:ArrayCollection>
<s:Button label="Button" />
<s:Rect fill="{fillColor}" width="20" height="20"/>
<s:Ellipse fill="{fillColor}" width="20" height="20"/>
<s:DropDownList />
</s:ArrayCollection>
</s:dataProvider>
</s:DataGroup>
That's all pretty cool but it's not what I needed. I just needed something that can present my Person object. So in this case we need to create a Custom ItemRenderer. This is a very easy thing to do and the end result is a lot better then the Repeater solution.
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:dataProvider>
<s:ArrayCollection>
<local:Person firstName="Alain" lastName="Hufkens"/>
<local:Person firstName="Hugh" lastName="Hefner"/>
<local:Person firstName="Jimi" lastName="Hendrix"/>
</s:ArrayCollection>
</s:dataProvider>
</s:DataGroup>
And this is the code for the PersonItemRenderer:
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Declarations>
<s:SolidColor id="normalColor" color="#000000"/>
<s:SolidColor id="hoveredColor" color="#FF0000"/>
</fx:Declarations>
<s:states>
<s:State name="normal"/>
<s:State name="hovered"/>
</s:states>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:Ellipse fill="{normalColor}" fill.hovered="{hoveredColor}"
width="10" height="10" />
<s:SimpleText text="{data.firstName} {data.lastName}"
color.hovered="#FF0000"/>
</s:ItemRenderer>
You can see the demo (including source) here.