Search code examples
actionscript-3apache-flexflex4flex4.5

Flex Mobile Spark List *conditional* ItemRenderer


I want to create a custom spark list which, based on a value (called type) in the data provider row, will set a conditional item renderer for that row.

<s:List>
    <s:dataProvider>
        <s:ArrayCollection>
            <s:source>
                <fx:Object type="type1" label="type 1 item" />
                <fx:Object type="type2" label="type 2 item" />
                <fx:Object type="type3" label="type 3 item" />
                <fx:Object type="type2" label="type 2 item" />
                <fx:Object type="type4" label="type 4 item" />
            </s:source>
        </s:ArrayCollection>
    </s:dataProvider>
</s:List>

So in essence the item renderer for each type of row would be different.

Why do I want to do this? Because using states in the item renderer for the different layouts is not reliable, it is hit and miss when you scroll quickly.

I did find this code for the mx list:

public class MultipleRenderersList extends List
{       
    override public function createItemRenderer(data:Object):IListItemRenderer
    {
        if (data.type == 'type1')
    {
        return new Type1Component;
    }
    else if (data.label == 'type2')
    {
        return new Type2Component;
    }
    return null;
}

But the spark list doesn't expose the 'createItemRenderer' or even anything similar. It does however have

override public function set itemRenderer(value:IFactory):void

But I have no way of accessing the dataProvider to do the conditional part of the problem.

Can anyone help?


Solution

  • Ok, so found it, I think :/

    http://sourceforge.net/adobe/flexsdk/wiki/Spark%20List/

    snippet

    private function introspectRole(item:Object):IFactory {
        if (item.role == "employee") {
            return new ClassFactory(EmployeeRenderer);
        } else if (item.role == "manager") {
            return new ClassFactory(ManagerRenderer);   
        } else { 
            return new ClassFactory(DefaultItemRenderer);
        }
    }
    

    And set the itemRendererFunction to this, apparently simple, but it works, so yeah.

    Thanks