Creating an alternating item renderer in a Spark List control in Flex 4 (redux)

In an earlier example, “Creating an alternating item renderer in a Spark List control in Flex 4”, we saw how you could create a custom item renderer in Flex 4 which repositions elements based on the current item renderer’s index in the data provider using the itemIndex property.

The following example shows how you can alternate between two separate item renderers using a custom item renderer function and the getItemIndex() method.

The following example(s) require Flash Player 10 and the Adobe Flex 4 SDK. To download the Adobe Flash Builder 4 trial, see www.adobe.com/products/flex/. To download the latest nightly build of the Flex 4 SDK, see opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4.

For more information on getting started with Flex 4 and Flash Builder 4, see the official Adobe Flex Team blog.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/04/09/creating-an-alternating-item-renderer-in-a-spark-list-control-in-flex-4-redux/ -->
<s:Application name="Spark_List_itemRendererFunction_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        xmlns:local="*">
 
    <fx:Script>
        <![CDATA[
            import skins.ItemRenEven;
            import skins.ItemRenOdd;
 
            private function itemRenFunc(item:Object):IFactory {
                if ((lst.dataProvider.getItemIndex(item) % 2) == 0) {
                    return new ClassFactory(ItemRenEven);
                } else {
                    return new ClassFactory(ItemRenOdd);
                }
            }
        ]]>
    </fx:Script>
 
    <s:List id="lst"
            itemRendererFunction="itemRenFunc"
            alternatingItemColors="[white,#EEEEEE]"
            horizontalCenter="0" verticalCenter="0">
        <s:layout>
            <s:VerticalLayout gap="0"
                    horizontalAlign="contentJustify"
                    requestedRowCount="7" />
        </s:layout>
        <s:dataProvider>
            <s:ArrayList>
                <local:Obj label="BorderContainer" icon="@Embed('assets/BorderContainer.png')" />
                <local:Obj label="Button" icon="@Embed('assets/Button.png')" />
                <local:Obj label="ButtonBar" icon="@Embed('assets/ButtonBar.png')" />
                <local:Obj label="CheckBox" icon="@Embed('assets/CheckBox.png')" />
                <local:Obj label="ComboBox" icon="@Embed('assets/ComboBox.png')" />
                <local:Obj label="DataGroup" icon="@Embed('assets/DataGroup.png')" />
                <local:Obj label="DropDownList" icon="@Embed('assets/DropDownList.png')" />
                <local:Obj label="Group" icon="@Embed('assets/Group.png')" />
                <local:Obj label="HGroup" icon="@Embed('assets/HGroup.png')" />
                <local:Obj label="HScrollBar" icon="@Embed('assets/HScrollBar.png')" />
                <local:Obj label="HSlider" icon="@Embed('assets/HSlider.png')" />
                <local:Obj label="Label" icon="@Embed('assets/Label.png')" />
            </s:ArrayList>
        </s:dataProvider>
    </s:List>
 
</s:Application>

The first custom item renderer, skins/ItemRenEven.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/04/09/creating-an-alternating-item-renderer-in-a-spark-list-control-in-flex-4-redux/ -->
<s:ItemRenderer name="ItemRenEven"
        xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx" 
        autoDrawBackground="true"
        dataChange="itemrenderer1_dataChangeHandler(event);">
 
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
 
            protected function itemrenderer1_dataChangeHandler(evt:FlexEvent):void {
                lbl.text = data.label;
                ico.source = data.icon;
            }
        ]]>
    </fx:Script>
 
    <s:HGroup left="3" right="3" top="3" bottom="3">
        <s:BitmapImage id="ico" />
        <s:Label id="lbl" width="100%" height="100%" verticalAlign="middle" />
    </s:HGroup>
 
</s:ItemRenderer>

The second custom item renderer, skins/ItemRenOdd.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/04/09/creating-an-alternating-item-renderer-in-a-spark-list-control-in-flex-4-redux/ -->
<s:ItemRenderer name="ItemRenOdd"
        xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx" 
        autoDrawBackground="true"
        dataChange="itemrenderer1_dataChangeHandler(event);">
 
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
 
            protected function itemrenderer1_dataChangeHandler(evt:FlexEvent):void {
                lbl.text = data.label;
                ico.source = data.icon;
            }
        ]]>
    </fx:Script>
 
    <s:HGroup left="3" right="3" top="3" bottom="3">
        <s:Label id="lbl" width="100%" height="100%" verticalAlign="middle" />
        <s:BitmapImage id="ico" />
    </s:HGroup>
 
</s:ItemRenderer>

And finally, our custom value object, Obj.as, is as follows:

/** http://blog.flexexamples.com/2010/04/09/creating-an-alternating-item-renderer-in-a-spark-list-control-in-flex-4-redux/ */
package {
    public class Obj {
        public function Obj() {
        }
 
        [Bindable]
        public var label:String;
 
        [Bindable]
        public var icon:Class;
    }
}

This entry is based on a beta version of the Flex 4 SDK and therefore is very likely to change as development of the Flex SDK continues. The API can (and will) change causing examples to possibly not compile in newer versions of the Flex 4 SDK.

One thought on “Creating an alternating item renderer in a Spark List control in Flex 4 (redux)

  1. Hi Peter,

    Thanks a lot for all your very good tutorials :-)

    I have a question with ItemRenderer. In fact, I want to use an ItemRenderer with a contract component like that :

    MyItemRendererSkin.mxml

    [HostComponent("com.sharehunter.flexclient.view.startup.home.itemrenderer.HuntItemListRenderer")]
    [ResourceBundle("i18n")]

    MyItemRenderComponent .as component


    package com.xxx.yyyy.zzzz
    {
    import flash.events.MouseEvent;

    import org.puremvc.as3.patterns.facade.Facade;

    import spark.components.Button;
    import spark.components.Label;
    import spark.components.SkinnableDataContainer;
    import spark.components.supportClasses.SkinnableComponent;

    [SkinState("normal")]
    [SkinState("disable")]

    public class MyItemRenderComponent extends SkinnableComponent
    {
    // Skin components contract
    // ...
    }
    }

    And in another .mxml, I’m using a list :

    At runtime, an Flex4 exception is catched in SkinnableComponent.as :

    Error: null
    at spark.components.supportClasses::SkinnableComponent/attachSkin()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\supportClasses\SkinnableComponent.as:632]
    at spark.components.supportClasses::SkinnableComponent/validateSkinChange()[E:\dev\4.0.0\frameworks\projects\spark\src\spark\components\supportClasses\SkinnableComponent.as:405]

    So, could you help me about ItemRenderer contract with a component (.As) ?

    Thank you very much Peter

    Anthony (angusyoung34@hotmail.com)

Comments are closed.