2013-02-11 48 views
0

我已經創建了自定義IconItemRenderer,其中標籤&消息正在圖標上顯示(在我的情況下,它是一個大圖像)。我想在圖像加載期間隱藏兩個標籤&消息。所以我默認它們是隱形的。當圖像加載時,我會讓它們可見。Flex Mobile: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(); 

} 

一切工作正常,但如果我把另一個查看到Navigator,並回到了這裏查看我的IconItemRenderer是,系統會創建另一個IconItemRenderer實例,也沒有標籤或消息或圖像是不可見的(因爲我的默認值)。

那麼我怎麼能早些使用 crated IconItemRenderer實例?

或者是否可以使用單個IconItemRenderer實例(如單數)?

或是否有任何EventDispathcer這表明項目中的數據已存在?

+0

它通常是有幫助的,以顯示你的代碼,在這種情況下,你的渲染器的代碼,所以我們可以得到正在發生的事情的一個更好的主意。 – 2013-02-11 07:36:28

+0

當然。新增代碼示例 – 2013-02-11 07:43:43

回答

0

請注意,作爲移動設備的優化,我相信移動項呈示器類會對圖像進行一些緩存(不像Web上,它只依賴於瀏覽器緩存中的圖像)。這可能就是爲什麼你沒有得到另一個完整的事件。

那麼我該如何使用先前創建的IconItemRenderer實例呢?

您不應嘗試或期望重新使用渲染的早期實例。 Flex List控件使用對象池來回收項目渲染器。該列表根據需要創建儘可能多的渲染器以在屏幕上顯示內容。當您滾動列表時,它會重新使用這些渲染器來顯示滾動到視圖中的新元素(稍後會詳細介紹這些內容)。你不應該試圖繞過這一行爲,這是很有效的:)

或是否有可能使用單IconItemRenderer實例(如 單身)?

不,如上所述,列表使用對象池並重新使用它創建的渲染器實例,因爲它認爲合適。單例模式在這裏並不適用。

或有任何事件Dispathcer這表明在項目 數據已經存在?

我不知道一個事件,說「嘿,這張圖片已經加載」。但是,當Flex使用項目渲染器時(無論是第一次還是重新使用它),它將設置渲染器的data屬性。 data屬性的setter調度「dataChange」事件。

因此,您可以偵聽此事件或覆蓋data屬性的setter,以瞭解渲染器何時獲取數據。現在您可以使用兩種方法:

設置數據時,確定傳入的數據是調用新圖像還是先前顯示的圖像。如果數據不同,請監聽COMPLETE事件以瞭解當前正在加載圖像的時間。

如果數據與以前相同,只需使標籤/消息對象可見即可。

這可能會也可能不會工作...另一個想法是何時設置數據,以通過檢查圖像的bytesLoadedbitmapData屬性嘗試推斷圖像是否已加載。

通過執行此類操作,可以使重寫的setter方法中的數據(或「dataChange」事件的事件處理程序)中的圖像/標籤/消息對象可見,以處理圖像已經存在的情況加載。

+0

我試過兩種變體,但在第一種情況下,沒有關於前一圖像的數據。在第二種情況下'bytesLoaded'等於'NaN',如果Image從'Cache'打出 – 2013-02-12 06:10:02

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

} 

我認爲這將解決這一問題