Apache flex ItemRenderer切换URL加载程序图像

Apache flex ItemRenderer切换URL加载程序图像,apache-flex,actionscript-3,air,blackberry-playbook,Apache Flex,Actionscript 3,Air,Blackberry Playbook,我甚至不知道如何解释这种行为,但我会试试。我从需要基本身份验证的外部url加载图像,因此我使用URLLoader从唯一ID加载图像。该ID被传递到itemrenderer,然后继续加载图像。但当我滚动时,图像会自动切换。如果我加载的图像超过7张左右,它就会开始重复图像 Youtube错误视频: 相关代码: <s:ItemRenderer name="RandomItemRenderer" creationComplete="init();" xmlns:fx="h

我甚至不知道如何解释这种行为,但我会试试。我从需要基本身份验证的外部url加载图像,因此我使用URLLoader从唯一ID加载图像。该ID被传递到itemrenderer,然后继续加载图像。但当我滚动时,图像会自动切换。如果我加载的图像超过7张左右,它就会开始重复图像

Youtube错误视频:

相关代码:

<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>


ItemRenders是可重用和缓存的,即在列表中只创建有限的计数来填充其区域(rowCount+-couple)。当您滚动时,新的渲染器不会被实例化,而是滚动出的渲染器会向上或向下移动,并填充新数据

这就是为什么您不能依赖于
creationComplete
事件,对于渲染器的每个实例,它只会触发一次

解决方案是覆盖
数据
setter,并在那里构建所需的行为:

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

有用的链接:

Ah不知道这一点——如果你能提供一个快速的例子,或者提供一个关于如何覆盖数据的链接,那就太棒了。谢谢这是不是让表演变得超级滞后?它是否会在每次项目不在视图中时获取图像,然后再返回视图,因为它看起来就是这样做的。好吧,这取决于您优化渲染器、对已下载的项目使用静态缓存、最小化新对象的创建等。实际上,我想知道1)为什么不嵌入nullcovertart.jpg,2)为什么通过
covertarimage
使用奇怪的图像加载和绑定。但是所有这些建议都偏离了本次对话的主题。静态缓存可能是一种解决方案,我也可以使用SQLite数据库来存储图像。至于nullCoverArt——当服务器API(我无法控制)返回不可用封面艺术的IO错误时使用。在给定标题basic auth的情况下,coveratimage函数是获取图像的唯一方法。如果有更好的方式,我想听听,所以我改变了我的方式,并学习:)