1

I have a list with time related data. the item renderers display this time. I would like to make the item renderers refresh their state/labels upon the tick of a timer.

to which event should I add a listener within the renderer, and how do I trigger such event from the list?

Dan
  • 1,163
  • 14
  • 34

3 Answers3

1

Hmm.. Usually you don't want to manipulate the item renderer directly. Typically you would update the collection.

If the timer reference is originally set from the data provider, you might want to set a timer and manipulate that property in the collection...

Something like this:

//Timer listener function (dp is data provider)
protected function handleTimerEvent(event:timerEvent):void
{
    for(var i:int = 0; i < dp.length; i++)
    {
        var o:Object = dp.getItemAt(i);
        o.minutes += 1;

        if(o.minutes == 60)
        {
            o.minutes = 0;
            o.hour += 1
        }
    }

    dp.refresh();
}

If minutes and hour is referenced in your item renderer you should see it update for each one. Of course, you would have to add better logic to handle other date stuff. You may want to make use of the date class to show more accurate time information.

Using the timer event in the item renderer may give you a performance hit depending on the length of your dataprovider. Say you have 100 rows of data, that's 100 timer events!

Victor Diaz
  • 92
  • 1
  • 2
  • 12
  • the idea was to have a single timer (and its handler) in the list. the dataprovider elements have attributes set in terms of delta time since the start of the timer (i.e. timer.start() ). what i wanted was a way of letting the itemrenderers know that they should recompute the delta times and render accordingly with respect of now. Traversing the whole collection is an alternative i was trying to avoid since i wanted to preserve it as read-only as possible (it's a mostly read-only control i'm writing) – Dan Feb 03 '12 at 17:22
  • Either way, manipulating the dp directly or modifying the data properties in the item renderer has the same effect. They both update the dp. It's a referenced object and resides in the same memory location. The difference is the IR does what it's suppose to do (render the data) and your data manipulation happens outside. Either way will work, but setting a timer in the IR is not performance friendly. Even if the IR reuses the object, you will have as many items are displayed dispatching TimerEvents vs one TimerEvent outside of the IR. – Victor Diaz Feb 03 '12 at 20:38
0

The simplest approach, given the information would be to use a Timer to cause a refresh, and calculate the time difference in a binding expression or inside commitProperties():

    <?xml version="1.0" encoding="utf-8"?>
    <s:ItemRenderer 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"
                    initialize="init()"
                    >

        <fx:Script>
            <![CDATA[

                private var timer:Timer = new Timer(1000);

                private function init():void
                {
                    timer = new Timer(1000);
                    timer.addEventListener(TimerEvent.TIMER, timer_timerHandler );
                    timer.start();
                }

                private function timer_timerHandler(event:TimerEvent):void
                {
                    // cause a redraw
                    invalidateProperties();
                }

                protected override function commitProperties():void
                {
                    super.commitProperties();

                    var date:Date = new Date();
                    date.seconds += data.timeOffset;
                    displayDate = dateFormatter.format(date);
                }

                [Bindable]
                private var displayDate:String;

            ]]>
        </fx:Script>

        <fx:Declarations>
            <s:DateTimeFormatter id="dateFormatter" dateTimePattern="HH:mm:ss" />
        </fx:Declarations>

        <s:Label text="{data.label} - {displayDate}"/>

    </s:ItemRenderer>
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
  • i was thinking of having the timer on the list, rather than on the item renderer (remember they get recycled). in Flex 3 there was invalidateList(), which had the effect of refreshing all renderers. I am looking for something similar on Spark. – Dan Feb 03 '12 at 05:41
-1

Try myList.invalidate() whenever you detect changes occurring.

Xaero Degreaz
  • 1,045
  • 11
  • 18