0
votes

I used flex sdk 4.5 for creating Adobe Air application. My application download files one by one. I show the currently downloading, pending and completed files in spark list. I used item Renderer that show the progress of the file and other states.

It works fine if selected files fit in current view. But as number of downloads increase, the Spark list shows vertical scroll. here I have the problem. Here file downloading functionality works fine, but if I try to scroll the list, File titles mix up or displayed out of order.

item renderer code:

<?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"
  creationComplete="onInit()"
  >

  <fx:Script><![CDATA[
    import com.streamingnetworks.hdvrwin.vo.DownloadInfo;

    import mx.events.CloseEvent;

    [Bindable]private var downloadInfo:DownloadInfo;
    private var url:String = "";
    private var fileName:String = "";

    private function onInit():void
    {
      downloadInfo = data as DownloadInfo;
      downloadInfo.addEventListener("Progress", onProgress);
      downloadInfo.addEventListener("DownloadComplete", onComplete);
      prog.label = "Downloading %3%%";
      lblPath.text = " - " + downloadInfo.getPathIp();
      trace("Downloading: " + downloadInfo.name);
    }

    private function onProgress(e:Event):void
    {
      prog.setProgress(downloadInfo.downloadedBytes, downloadInfo.totalBytes);
      lblState.text = downloadInfo.getDownState();
    }

    private function onComplete(e:Event):void
    {
      prog.label = "Download Complete";
    }

    protected function onClose(event:CloseEvent):void
    {      
      downloadInfo.state = "deleted"
    }

  ]]></fx:Script>

  <s:TitleWindow top="0" left="0" right="0" bottom="0" dropShadowVisible="false"
    title="{'Downloading ' + downloadInfo.name}" close="onClose(event)">
    <mx:ProgressBar id="prog" label="" mode="manual" 
      trackHeight="20" labelPlacement="center" width="100%"/>
    <s:HGroup top="25">
      <s:Label id="lblState" text="Downloading 0 Bytes of 0 Bytes."/>
      <s:Label id="lblPath"/>
    </s:HGroup>
  </s:TitleWindow>

</s:ItemRenderer>

here the list control where I am using that renderer

<s:List id="lstControls" dataProvider="{urlArr}"
    itemRenderer="ItemRenderer"
    left="5" right="5" bottom="5" top="40"/>

urlArr is an arrayList that contains only url in string form.

How can I solve this problem? Any Help will be appreciated. Thanks

2

2 Answers

2
votes

Your renderers are not updating correctly because you are setting your data when the renderer is created - but you should be overriding the set data method, eg:

override public function set data(value:Object):void
{
    super.data = value;
    downloadInfo = data as DownloadInfo;
    downloadInfo.addEventListener("Progress", onProgress);
    downloadInfo.addEventListener("DownloadComplete", onComplete);
    prog.label = "Downloading %3%%";
    lblPath.text = " - " + downloadInfo.getPathIp();
    trace("Downloading: " + downloadInfo.name);
}

And remove the creationComplete listener.

1
votes

As a better practice. Have all the data your progress bars will need all ready in the data provider and have them react ONLY to changes in the data. Adding and removing listeners and binding internally will only cause you grief. Renderers do not live forever and are re-used inside of list components. Manage everything through overriding set data().

In this example I would create a model object with a name like FileDownloadInfo and properties such as .downloadProgress .fileName and .ipAddress then have the renderer update on property change events of .downloadProgress