Flex Mobile:IconItemRenderer的单个实例

时间:2013-02-11 07:29:11

标签: actionscript-3 flex air flex4.5

我创建了自定义IconItemRenderer,其中标签&消息正在图标上显示(在我的情况下,它是一个大图像)。我想隐藏标签和&正在加载图像期间的消息。所以我默认它们是隐形的。加载图像后,我将它们显示出来。

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();

}

一切正常,但是如果我将另一个View推入Navigator并返回我的IconItemRenderer所在的View,系统会创建另一个IconItemRenderer实例,并且标签或消息或图像也不可见(因为我的默认值)。

那么如何使用早期的 crated IconItemRenderer实例?

或者是否可以使用单个 IconItemRenderer实例(如单机版)?

或是否有Event Dispathcer表示商品中的数据已存在?

2 个答案:

答案 0 :(得分:0)

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

  

那我怎样才能使用之前创建的IconItemRenderer实例?

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

  

或者是否可以使用单个IconItemRenderer实例(如a   单)?

不,如上所述,该列表使用对象池并重新使用它在其认为合适时创建的渲染器实例。单身模式真的不适用于此。

  

或是否有任何Event Dispathcer指示项目中的数据   已经存在?

我不知道有一个事件说“嘿这个图像已经被加载”。但是,当Flex使用项呈示器时(无论是第一次还是重新使用它),它将设置呈现器的data属性。 data属性的setter调度“dataChange”事件。

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

设置数据后,确定传入的数据是否正在调用新图像或先前显示的图像。如果数据不同,请监听COMPLETE事件,以了解当前正在加载图像的时间。

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

这可能也可能不起作用......另一个想法是设置数据时,通过检查图像的bytesLoadedbitmapData属性来尝试推断图像是否已加载。

通过执行此类操作,您可以在覆盖的数据集setter方法(或“dataChange”事件的事件处理程序)中显示图像/标签/消息对象,以处理已加载图像的情况

答案 1 :(得分:0)

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();

}

我认为这将解决问题