深入探讨SparkList组件的使用技巧与实践
立即解锁
发布时间: 2025-08-18 00:51:39 阅读量: 1 订阅数: 6 

### 深入探讨 Spark List 组件的使用技巧与实践
#### 1. Spark List 组件概述
Spark List 组件在开发中应用广泛,它和 Spark ButtonBar 组件都继承自 `spark.components.SkinnableDataContainer` 类。该类允许通过数据提供者生成子控件,还支持排序、过滤、重新排序等操作,并且能设置可视化组件作为项渲染器和项编辑器。Spark List 组件具有项渲染器回收机制,比如创建 1000 个项,但某一时刻仅 20 个可见,那么只会创建 20 个项渲染器,滚动列表时会刷新每个渲染器的数据以显示正确的值。
#### 2. 创建 Spark List 的项渲染器
- **问题**:需要为 Spark List 组件创建自定义项渲染器。
- **解决方案**:继承 `spark.components.supportClasses.ItemRenderer` 类,然后使用全限定类名或 `<fx:Component>` 标签将该组件赋值给 List 的 `itemRenderer` 属性。
- **操作步骤**:
- **使用 `<fx:Component>` 标签**:
```xml
<fx:Script>
<![CDATA[
[Bindable]
public var provider:ArrayCollection;
public function init():void {
provider = new ArrayCollection(["one", "two", "three", "four", "five",
"six"]);
}
]]>
</fx:Script>
<s:List id="list" dataProvider="{provider}" selectedIndex="0">
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer>
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:Rect left="0" right="0" top="0" bottom="0">
<s:fill>
<s:SolidColor color="0x000088" alpha="0.6"/>
</s:fill>
</s:Rect>
<s:Rect left="0" right="0" top="0" bottom="0">
<s:fill>
<s:SolidColor color="0x008800" alpha="0.6"/>
</s:fill>
</s:Rect>
<s:Label text="{data}"/>
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>
```
- **定义单独类并使用全限定类名**:
```xml
<s:List id="list" dataProvider="{provider}"
itemRenderer="oreilly.cookbook.flex4.SampleRenderer"/>
```
这里的 `SampleRenderer` 需要继承 `ItemRenderer` 类并定义三个状态:
| 状态 | 描述 |
| ---- | ---- |
| normal | 项未被悬停或选中时显示 |
| hovered | 用户悬停在项渲染器上时显示 |
| selected | 用户通过点击或使用键盘选中项渲染器时显示 |
#### 3. 创建可编辑的 Spark List
- **问题**:需要创建一个所有项都可编辑的 Spark List。
- **解决方案**:创建一个具有选中状态的项渲染器,并在该状态下包含 `TextInput` 或其他控件。
- **操作步骤**:
```xml
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Metadata>
[HostComponent("spark.components.List")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.List;
protected function dataChangeHandler():void {
this.data = textInput.text;
currentState = "normal";
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" enterState="textInput.setFocus()"/>
</s:states>
<s:Rect height="{height}" width="{hostComponent.width}">
<s:fill>
<s:SolidColor color="0xeeffff"
alpha="0" alpha.hovered="0.1" alpha.selected="0.4" />
</s:fill>
</s:Rect>
<s:Label text="{data}" includeIn="hovered, normal"/>
<s:TextInput includeIn="selected" id="textInput" text="{data}"
enter="dataChangeHandler()" width="100"/>
</s:ItemRenderer>
```
为确保用户按键不会触发列表导航,可禁用 `findKey()` 方法:
```xml
<s:List xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Script>
<![CDATA[
override protected function findKey(eventCode:int) : Boolean {
return false;
}
]]>
</fx:Script>
</s:List>
```
实现 List 和项渲染器:
```xml
<flex4:KeyNavDisabledList itemRenderer="oreilly.cookbook.flex4.ItemEditor"
dataProvider="{provider}"/>
```
#### 4. 滚动到 Spark List 中的特定项
- **问题**:想在 Spark List 中滚动到数据提供者中的特定索引位置。
- **解决方案**:使用 Spark List 的 `ensureIndexIsVisible()` 方法。
- **操作步骤**:该方法签名为 `ensureIndexIsVisible(index:int):void`,它利用 `DataGroup` 中 `LayoutBase` 的 `getScrollPositionDeltaToElement()` 方法,无论列表使用水平、垂直还是平铺布局,都能使指定索引的项可见。
#### 5. 更改 Spark List 的布局
- **问题**:想创建一个水平布局或网格布局的 Spark List。
- **解决方案**:创建一个包含 `TileLayout` 的 `DataGroup` 的 Skin 类,并将其赋值给 List。
- **操作步骤**:
```xml
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Metadata>
[HostComponent("spark.components.List")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import spark.components.List;
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
<s:State name="selected"/>
</s:states>
<s:DataGroup id="dataGroup" height="{hostComponent.height}"
width="{hostComponent.width}">
<s:layout><s:TileLayout clipAndEnableScrolling="true"/></s:layout>
</s:DataGroup>
</s:Skin>
```
#### 6. 创建嵌套的 Spark List
- **问题**:希望在一个父列表中嵌套多个 List 对象。
- **解决方案**:创建一个包含 List 的项渲染器,并监听嵌套 List 实例的 `SelectionEvent`。
- **操作步骤**:
```xml
<fx:Script>
<![CDATA[
import spark.events.RendererExistenceEvent;
import mx.collections.ArrayCollection;
private var rendererArray:Array = [];
[Bindable]
private var arr:ArrayCollection;
private function init():void {
arr = new ArrayCollection([
new ArrayCollection(["one", "two", "three", "four", "five"]),
new ArrayCollection(["uno", "dos", "tres", "quatro",
"cinco"]),
new ArrayCollection(["un", "deux", "trois", "quatre",
"cinq"]),
new ArrayCollection(["一", "二", "三","四","五"])]);
}
private function handleRendererAdd(event:RendererExistenceEvent):void {
rendererArray.push(event.renderer);
event.renderer.addEventListener("selectionEvent", selected);
}
private function handleRendererRemove(event:RendererExistenceEvent):
void {
rendererArray.splice(rendererArray.indexOf(event.renderer), 1);
event.renderer.removeEventListener("selectionEvent", selected);
}
private function selected(event:Event):void {
for(var i:int = 0; i < rendererArray.length; i++) {
if(event.target != rendererArray[i]) {
rendererArray[i].currentState = "normal";
}
}
}
]]>
</fx:Script>
<s:List itemRenderer="oreilly.cookbook.flex4.NestedRenderer" id="list"
dataProvider="{arr}" rendererAdd="handleRendererAdd(event)"
rendererRemove="handleRendererRemove(event)"/>
```
`NestedRenderer` 类:
```xml
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
height="15" mouseDown="mouseDownHandler(event)">
<fx:Metadata>
[Event( name="selectionEvent", type="flash.events.Event" )]
</fx:Metadata>
<fx:Script>
<








