2011-09-07 51 views
0

我甚至不知道如何解释这种行为,但我会尝试。我从需要基本身份验证的外部URL加载图像,因此我使用URLLoader从唯一ID加载图像。该ID传递给itemrenderer,然后继续加载图像。但是当我滚动时,图像自己切换。如果我负荷超过7倍的图像或所以它开始重复图像....ItemRenderer切换URLLoader图片

误差的

的Youtube视频: http://www.youtube.com/watch?v=ZYoqlS14gWQ

相关的代码:

<s:ItemRenderer name="RandomItemRenderer" creationComplete="init();" 
      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="false"> 
<s:states> 
    <s:State name="normal" /> 
    <s:State name="hovered" /> 
    <s:State name="selected" /> 
</s:states> 

<fx:Script> 
    <![CDATA[ 
     import flash.net.URLLoader; 
     import flash.net.URLLoaderDataFormat; 
     import flash.net.URLRequest; 
     import flash.net.URLRequestHeader; 
     import flash.net.URLRequestMethod; 

     import mx.utils.ObjectProxy; 

     import customclasses.Settings; 

     [Bindable] private var coverArtImage:Image; 
     private var myCoverArtLoader:URLLoader; 

     [Bindable] private var coverArtSource:String; 

     private function init():void { 
      get_coverArt(); 
     } 

     private function get_coverArt(): void { 
      if (!data.coverArt) { 
       set_nullCoverArt(); 
      } else { 
       var requestString:String = "/rest/getCoverArt.view?v=1.5.0&c=AirSub&id=" + data.coverArt; 
       var requestURL:String = Settings.ServerURL + requestString; 

       myCoverArtLoader = new URLLoader(); 
       var myRequest:URLRequest = new URLRequest(); 

       var authHeader:URLRequestHeader = new URLRequestHeader(); 
       authHeader.name = 'Authorization'; 
       authHeader.value = 'Basic ' + Settings.EncryptedCreds(); 

       myRequest.requestHeaders.push(authHeader); 
       myRequest.url = requestURL; 
       myRequest.method = URLRequestMethod.GET; 
       myCoverArtLoader.dataFormat = URLLoaderDataFormat.BINARY; 

       myCoverArtLoader.addEventListener(Event.COMPLETE, set_coverArt); 
       myCoverArtLoader.addEventListener(IOErrorEvent.IO_ERROR, set_failedCoverArt); 
       myCoverArtLoader.load(myRequest); 
      } 
     } 

     private function set_coverArt(evt:Event) : void { 
      coverArtImage = new Image(); 
      coverArtImage.source = myCoverArtLoader.data;   
      myCoverArtLoader.removeEventListener(Event.COMPLETE, set_coverArt); 
     } 

     private function set_nullCoverArt() : void { 
      coverArtImage = new Image(); 
      coverArtImage.source = "assets/nullCoverArt.jpg"; 
     } 

     private function set_failedCoverArt() : void { 
      coverArtImage = new Image(); 
      coverArtImage.source = "assets/nullCoverArt.jpg"; 
      myCoverArtLoader.addEventListener(IOErrorEvent.IO_ERROR, set_nullCoverArt); 
     } 

    ]]> 
</fx:Script> 

<s:Image source.normal="assets/coverOutline.png" source.selected="assets/coverOutlineYellow.png" source.hovered="assets/coverOutlineYellow.png" 
     height="226" width="226" /> 

<s:VGroup top="4.5" bottom="5" width="200" horizontalAlign="center" letterSpacing="10" 
      paddingBottom="5" paddingTop="9" verticalAlign="middle" x="13.5"> 
    <s:Image id="ui_imgCoverArt" width="200" height="200" source="{coverArtImage.source}"/> 
    <s:Label text="{data.title}" width="160" styleName="RandomList" /> 
</s:VGroup> 

回答

2

itemRenderer是可重复使用和缓存,即在列表中创建的计数仅限于填充其区域(rowCount + - couple)。当你滚动时,新的渲染器不会被实例化,而是被滚动出来的一个渲染器会上下移动并充满新的数据。

这就是为什么你不能依靠creationComplete事件,它会被渲染一次渲染器的每个实例。

的解决方案是重写data setter和建立有需要的行为:

override public function set data(value:Object):void 
{ 
    super.data = value; 
    get_coverArt(); 
} 

有用的链接:How flex itemRenderer works ? (their life cycle)

+0

丫不知道 - 如果你能提供一个简单的例子或也许链接如何覆盖真棒的数据。谢谢! –

+0

检查更新回答 – moropus

+0

太棒了 - 谢谢!我今晚会尝试。 –