原文地址:http://www.adobe.com/cn/devnet/flex/articles/itemrenderers_pt2.html
在本系列的第 1 部分中, 我向您展示瞭如何創建內聯 itemRenderer-這種 itemRenderer 的 MXML 標記和 ActionScript 代碼與使用該 itemRenderer 的列表位於同一文件中。代碼與文件中的其餘代碼內聯。
您應該還記得我說過, 應該將內聯 itemRenderer 視作單獨的類。事實上, Flex 編譯器提取這些內聯代碼併爲您創建類。內聯 itemRenderer 的優勢在於代碼與列表位於同一位置, 但是如果 itemRenderer 變得複雜時, 這又變成了劣勢。本文中我將向您展示如何自己創建類。
將 itemRenderer 提取到一個外部文件有幾個優勢:
- itemRenderer 可輕鬆用於多個列表中
- 代碼更容易維護
- 可以使用 Flex Builder 的“設計”視圖草擬出最初的 itemRenderer
本系列包含以下文章:
要求
爲了充分利用本文, 您需要以下軟件和文件:
Flex Builder 3
必要條件:
要從本文中受益, 您最好熟悉 Flex Builder 和 ActionScript 3.0。
MXML itemRenderer
在第 1 部分中, 您看到有一個複雜的 itemRenderer 用於 DataGrid:
itemRenderer 基於 HBox, 包含一個 Image 和一個 Text, 並且根據項目記錄的 pubDate
字段設置背景色。可以使用以下步驟將同一 itemRenderer 編寫爲一個外部文件:
- 如果您使用 Flex Builder, 請新建一個 MXML Component 文件 (我將我的文件命名爲 GridColumnSimpleRenderer, 您可以隨意命名), 將根標記設置爲
HBox
。不必擔心大小。 - 如果您只使用 SDK, 請新建一個 MXML 文件 (將它命名爲 GridColumnSimpleRenderer.mxml), 將根標記設置爲
HBox
。 -
在文件打開時, 複製
<mx:HBox>
與</mx:HBox>
之間的所有內容, 但不要複製那些標記, 因爲文件中已有它們。結果應該如下: - 保存此文件。
現在修改 DataGridColumn 定義, 方法是刪除內聯 itemRenderer 並將它替換爲以下內容:
<mx:DataGridColumn headerText="Title" dataField="title" itemRenderer="GridColumnSimpleRenderer">
現在運行這個應用程序。您會大喫一驚。因爲行很高。這是因爲 itemRenderer 上的 height="300"
。
決定 itemRenderer 的寬度和高度
List 控制始終設置 itemRenderer 的寬度。本例中將忽略明確的 width="400"
。您應當編寫自己的 itemRenderer, 假設用戶更改列或列表寬度是寬度會更改。
高度則是另一回事。如果列表設置了明確的 rowHeight
, 它會將這個高度強加到各行, 忽略您對 itemRenderer 設置的任何高度。但是, 如果您將列表的 variableRowHeight
屬性設置爲 true
, 則列表會慎重考慮 itemRenderer 的高度。在本例中, 高度明確設置爲 300, 所以各行爲 300 像素高。
要修復它, 請從 itemRenderer 文件中刪除明確高度, 應用程序即可正確運行。
動態更改 itemRenderer
本例覆蓋了 set data()
函數以檢查數據並設置 itemRenderer 的 backgroundColor
。這十分常見。覆蓋 set data()
使您能截取爲新行更改數據的時間, 並且您可以作出樣式更改。
常見錯誤爲:
- 忘記調用
super.data = value;
。這是致命錯誤-它會把 itemRenderer 弄亂。 - 忘記重置樣式 (如果任何測試失敗)。當
pubDate
是將來時, 可能只設置顏色會比較誘人, 但您必須記住, itemRenderer 是循環使用的, 所以else
語句很有必要。
ActionScript itemRenderer
現在, 您將編寫另一個 itemRenderer, 這次使用 ActionScript 類。在上一篇文章中, 有一個 TileList 包含這個內聯 itemRenderer:
您將把它轉變爲一個 ActionScript 外部 itemRenderer。您需要執行以下步驟:
-
新建一個 ActionScript 類。將它命名爲 BookTileRenderer.as 並使它擴展 HBox, 就像內聯 itemRenderer 那樣。
-
創建成員變量, 用於存放子組件的引用。
-
覆蓋
createChildren()
函數以創建子組件, 並將它們添加到 HBox。我準備通過這一代碼顯示父子關係。同時, 確保在 Buy 按鈕中包含一個事件偵聽器。
-
覆蓋
commitProperties()
函數, 並從數據設置用戶界面控制。 -
爲 Buy 按鈕添加單擊事件處理函數。
-
將主應用程序中的 TileList 修改爲使用 itemRenderer ActionScript 類。只需刪除
inlineItemRenderer
並將它替換爲標記中的itemRenderer
屬性。
如果要使用一個現有容器類, 如 HBox, 我不會使用 ActionScript 這樣做。您會發現它比使用 MXML 文件複雜, 並且老實說, 性能方面幾乎沒有任何優勢。
可重用的 itemRenderer
以下是一個 itemRenderer 示例, 它使用 CurrencyFormatter 顯示一個數值。我稱之爲 PriceFormatter:
這個 itemRenderer 的關鍵部分以紅色標出, 設置可綁定變量 formattedValue
。首先, 您會發現 <mx:CurrentFormatter>
使用 id
cfmt
定義爲 MXML 標記 (如果您願意, 也可以使用 ActionScript 這樣做)。在上例中, formattedValue
設置爲 CurrentFormatter 的 format()
函數的調用結果。
此函數將 Number 作爲其參數類型, 所以值被轉換爲 Number-這是因爲列表的 dataProvider 是 XML 並且 XML 中的所有內容是文本; 如果爲數據使用 Object 並且您有實際數值, 執行 Number 轉變將是無害的。
如您所知, 數據是存放 itemRenderer 所顯示項目的屬性。使用 [ ]
記號是訪問數據項目字段的另一種方法。例如, data['price']
是價格列。但是爲了使這個 itemRenderer 可重用, 您不能爲特定字段編碼, 所以需要一種更普通的方法。
此時, listData
登臺亮相。實施 IDropInListItemRenderer 接口的所有 Flex 組件都有一個 listData
屬性。
注意: Text、Label、Button、CheckBox 等大多數控制都實施 IDropInListItemRenderer。HBox、Canvas 等大多數容器不實施此接口。如果要在擴展 Container 的 itemRenderer 中使用 listData
, 您必須自己實施 IDropInListItemRenderer; 我將在下一篇文章中討論這個問題。
除了其他內容, 提供給 itemRenderer 的 listData
還包含 rowIndex
和控制, 該控制擁有 itemRenderer-DataGrid、List 或 TileList。將 itemRenderer 用於 DataGrid 時, listData
實際上是一個 DataGridListData 對象-它包含 columnIndex 以及與 DataGridColumn 關聯的 dataField。以下是上述語句的明細, 從內部開始:
listData as DataGridListData
-它將 listData 轉換爲 DataGridListData 對象, 使您能訪問它的 dataField.dataField
-該字段用於渲染的列。它使這個 itemRenderer 變得一般。可以將這個 itemRenderer 用於多個列。在本例中, dataField 是“price”。data[ ... ]
-它訪問項目中特定字段的數據。在本例中, 它是價格列。Number( ... )
-它將值轉換爲 Number, 因爲 format() 函數需要一個 Number 參數。cfmt.format( ... )
-它將值格式化爲貨幣。
後續工作
實施 itemRenderer 時, 可使用您喜歡的任何語言。一些人只適用 ActionScript, 當然如果您具有 Flex 和 ActionScript 方面的經驗, 這很棒。MXML 也可以快速創建出簡單的 itemRenderer。
在第 3 部分 (即將推出) 中, 我將進一步討論 itemRenderer 與應用程序其餘部分之間的通信。