Actionscript 3 Flex Mobile:IconItemRenderer的单个实例

Actionscript 3 Flex Mobile:IconItemRenderer的单个实例,actionscript-3,apache-flex,air,flex4.5,Actionscript 3,Apache Flex,Air,Flex4.5,我已经创建了自定义的标签和消息显示在图标上(在我的例子中,它是一个大图像)。我想在加载图像期间隐藏标签和消息。所以我默认让他们看不见。当图像加载时,我会使它们可见 override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void { super.layoutContents(unscaledWidth, unscaledHeight); setElementP

我已经创建了自定义的标签和消息显示在图标上(在我的例子中,它是一个大图像)。我想在加载图像期间隐藏标签和消息。所以我默认让他们看不见。当图像加载时,我会使它们可见

override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
{
    super.layoutContents(unscaledWidth, unscaledHeight);

    setElementPosition(busyIndicator, (this.width - iconDisplay.width) / 2, (this.height - Dimensions.BUSY_INDICATOR_EDGE_LENGTH) / 2);
    setElementPosition(iconDisplay, (this.width - iconDisplay.width) / 2, 0);
    setElementPosition(labelDisplay, iconDisplay.x + 20, iconDisplay.y + iconDisplay.height / 4);
    setElementPosition(textFieldProductNumber, iconDisplay.x + 20, labelDisplay.y + labelDisplay.height + 10); 
    setElementPosition(messageDisplay, iconDisplay.x + 20, textFieldProductNumber.y + textFieldProductNumber.height);

    setElementSize(busyIndicator, Dimensions.BUSY_INDICATOR_EDGE_LENGTH, Dimensions.BUSY_INDICATOR_EDGE_LENGTH);
    setElementSize(textFieldProductNumber, labelDisplay.width, labelDisplay.height / 2);

    iconDisplay.addEventListener(Event.COMPLETE, onIconComplete);

    if(!isIconComplete)
    {
        busyIndicator.visible = true;
        iconDisplay.visible = false;
        labelDisplay.visible = false;
        textFieldProductNumber.visible = false;
        messageDisplay.visible = false;

    }
}

protected function onIconComplete(event:Event):void
{

    busyIndicator.visible = false;
    iconDisplay.visible = true;
    labelDisplay.visible = true;
    textFieldProductNumber.visible = true;
    messageDisplay.visible = true;  

    isIconComplete = true;

    iconDisplay.removeEventListener(Event.COMPLETE, onIconComplete);

    invalidateDisplayList();

}
一切正常,但如果我将另一个视图推到
导航器中
并返回到我的IconItemRenderer所在的视图,系统将创建另一个IconItemRenderer实例,并且nor标签、消息或图像不可见(因为我的默认值)

那么,我如何使用以前包装的
IconItemRenderer
实例呢

或者可以使用single
IconItemRenderer
实例(比如singletone)


或者是否有任何
dispatcher
表明项目中的数据已经存在?

请注意,作为移动设备的优化,我相信移动项目渲染器类会对图像进行一些缓存(与web不同,它只依赖于浏览器缓存中的图像)。这可能就是为什么您没有获得另一个完整事件的原因

那么,如何使用先前创建的IconItemRenderer实例呢

您不应该尝试或期望重用渲染的早期实例。Flex
List
控件使用对象池来回收项目渲染器。该列表根据需要创建尽可能多的渲染器,以便在屏幕上显示内容。当您滚动列表时,它将重新使用这些渲染器来显示已滚动到视图中的新元素(稍后将对此进行详细介绍)。你不应该试图规避这种行为,它相当有效:)

或者可以使用单个IconItemRenderer实例(例如 单身人士

不,如上所述,列表使用对象池,并根据需要重新使用它创建的渲染器实例。单例模式在这里并不适用

或者是否有任何事件dispatcher指示项中的数据 已经存在

我不知道有一个事件会说“嘿,这个图像已经加载了”。但是,当Flex使用项目渲染器时(无论是第一次还是重复使用),它都会设置渲染器的
数据
属性。
数据
属性的setter发送一个“dataChange”事件

因此,您可以侦听此事件或覆盖
数据
属性的setter,以了解渲染器何时获取其数据。现在,您可以使用两种方法:

设置数据时,确定传入的数据是调用新图像还是调用以前显示的图像。如果数据不同,请侦听完整事件,以了解图像在当前加载过程中的加载时间

如果数据与以前相同,只需使标签/消息对象可见即可

这可能有效,也可能无效。。。另一个想法是在设置数据时,通过检查图像的
bytesload
bitmapData
属性来尝试推断图像是否已加载

通过这样做,您可以使图像/标签/消息对象在数据的重写setter方法(或“dataChange”事件的事件处理程序)中可见,以处理图像已加载的情况

override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
{
   super.layoutContents(unscaledWidth, unscaledHeight);

   setElementPosition(busyIndicator, (this.width - iconDisplay.width) / 2, (this.height - Dimensions.BUSY_INDICATOR_EDGE_LENGTH) / 2);
   setElementPosition(iconDisplay, (this.width - iconDisplay.width) / 2, 0);
   setElementPosition(labelDisplay, iconDisplay.x + 20, iconDisplay.y + iconDisplay.height / 4);
   setElementPosition(textFieldProductNumber, iconDisplay.x + 20, labelDisplay.y + labelDisplay.height + 10); 
   setElementPosition(messageDisplay, iconDisplay.x + 20, textFieldProductNumber.y + textFieldProductNumber.height);

   setElementSize(busyIndicator, Dimensions.BUSY_INDICATOR_EDGE_LENGTH, Dimensions.BUSY_INDICATOR_EDGE_LENGTH);
   setElementSize(textFieldProductNumber, labelDisplay.width, labelDisplay.height / 2);

   if(iconContentLoader)
       ContentCache(iconContentLoader).enableCaching = false;

   iconDisplay.addEventListener(Event.COMPLETE, onIconComplete);

   if(!isIconComplete)
   {
       busyIndicator.visible = true;
       iconDisplay.visible = false;
       labelDisplay.visible = false;
       textFieldProductNumber.visible = false;
       messageDisplay.visible = false;

   }
}

protected function onIconComplete(event:Event):void
{

   busyIndicator.visible = false;
   iconDisplay.visible = true;
   labelDisplay.visible = true;
   textFieldProductNumber.visible = true;
   messageDisplay.visible = true;  

   isIconComplete = true;


   iconDisplay.removeEventListener(Event.COMPLETE, onIconComplete);

   invalidateDisplayList();

}

我认为这将解决问题

显示代码通常很有帮助,在本例中,显示渲染器的代码,这样我们可以更好地了解正在发生的事情。当然。添加了代码示例我尝试了这两种变体,但在第一种情况下,没有关于前一个图像的数据。在第二种情况下,
bytesload
等于
NaN
,如果图像是从
缓存中查询的