使用Flex AdvancedDataGrid可以在列表中展示树形结构,但默认的图标为文件夹及文件图标,如图。如果想修改图标,且只是简单替换默认图标可以使用如下方式:
<mx:AdvancedDataGrid folderOpenIcon="@Embed('assets/images/open.jpg')"
folderClosedIcon="@Embed('assets/images/close.jpg')"
defaultLeafIcon="@Embed('assets/images/leaf.jpg')">
但如果想根据数据不同,显示不同的图标会麻烦一些。如上图,要求不同部门显示不同图标,人员要根据职位显示不同图标。在测试过程中试过使用姓名列的itemRenderer,但这种方法只能改掉叶子节点的图标,非叶子节点的文件夹图标改不掉。后来试过直接使用AdvancedDataGrid的itemRenderer,但也没能实现想要的效果。最后还是从folderOpenIcon,folderClosedIcon,defaultLeafIcon入手,写一个类继承Image,根据数据不同赋不同的source值,代码如下:
package com.demo
{
import flash.events.Event;
import mx.controls.Alert;
import mx.controls.Image;
import mx.controls.advancedDataGridClasses.AdvancedDataGridGroupItemRenderer;
import mx.formatters.DateFormatter;
public class FolderAndLeafIcon extends Image
{
[Embed(source="assets/images/employee.jpg")]
private const employee:Class;
[Embed(source="assets/images/manager.jpg")]
private const manager:Class;
[Embed(source="assets/images/renli.jpg")]
private const renli:Class;
[Embed(source="assets/images/yanfa.jpg")]
private const yanfa:Class;
public function FolderAndLeafIcon()
{
super();
this.addEventListener(Event.ADDED_TO_STAGE, setIconSource);
}
private function setIconSource(event:Event):void{
var folderIcon:FolderAndLeafIcon = event.currentTarget as FolderAndLeafIcon;
if(folderIcon){
folderIcon.source = getIconSourceValue(folderIcon);
}
}
public function getIconSourceValue(folderIcon:FolderAndLeafIcon):Class{
var advancedGridGroupItemRender:AdvancedDataGridGroupItemRenderer = folderIcon.parent as AdvancedDataGridGroupItemRenderer;
var source:Class;
if(advancedGridGroupItemRender){
// 当advancedGridGroupItemRender.data包含dept,name,manager等属性时,当前是叶子节点
if (advancedGridGroupItemRender.data.hasOwnProperty("manager")) {
var m:int = advancedGridGroupItemRender.data.manager;
if (m == 1) {
source = manager;
}
else if (m == 0) {
source = employee;
}
}
else { // 非叶子节点
var dept:String = advancedGridGroupItemRender.listData.label;
if (dept == "人力") {
source = renli;
}
else if (dept == "研发") {
source = yanfa;
}
}
}
return source;
}
}
}
上面代码获得advancedGridGroupItemRender是关键,还有就是怎样获得数据也是关键,advancedGridGroupItemRender.listData.label获得的是当前单元格的文本内容,advancedGridGroupItemRender.data获得的是当前行的数据。非叶子节点时advancedGridGroupItemRender.data得到的行数据是空的,只能通过advancedGridGroupItemRender.listData.label得到当前单元格文本内容。测试时在这个地方花费了很多时间,一直得不到data中的属性值。
下面看一下调用的代码(注意第一列不能设置visible="false",否则无法显示数据):
<fx:Declarations>
<mx:GroupingCollection id="gc" source="{dataSource}">
<mx:Grouping>
<mx:GroupingField name="dept"/>
</mx:Grouping>
</mx:GroupingCollection>
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.demo.FolderAndLeafIcon;
import mx.collections.ArrayCollection;
[Bindable]
public var dataSource:ArrayCollection = new ArrayCollection([
{dept:"人力", name:"张三", sex:0, age:25, telnumber:"123456", manager:1},
{dept:"人力", name:"李四", sex:1, age:20, telnumber:"123456", manager:0},
{dept:"研发", name:"王五", sex:1, age:21, telnumber:"123456", manager:1},
{dept:"研发", name:"赵六", sex:0, age:22, telnumber:"123456", manager:0},
{dept:"研发", name:"钱七", sex:1, age:23, telnumber:"123456", manager:0}
]);
]]>
</fx:Script>
<mx:AdvancedDataGrid dataProvider="{gc}" initialize="gc.refresh()" defaultLeafIcon="{FolderAndLeafIcon}"
folderOpenIcon="{FolderAndLeafIcon}" folderClosedIcon="{FolderAndLeafIcon}" >
<mx:columns>
<mx:AdvancedDataGridColumn headerText="姓名" dataField="name" />
<mx:AdvancedDataGridColumn headerText="性别" dataField="sex" itemRenderer="com.demo.SexRenderer"/>
<mx:AdvancedDataGridColumn headerText="年龄" dataField="age" textAlign="center"/>
<mx:AdvancedDataGridColumn headerText="电话" dataField="telnumber" textAlign="center"/>
</mx:columns>
</mx:AdvancedDataGrid>
上面性别列定义了itemRenderer,显示图片,代码如下:
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
[Embed(source="assets/images/male.jpg")]
private const male:Class;
[Embed(source="assets/images/female.jpg")]
private const female:Class;
private function getIcon(sex:String):Class {
if (sex == "1") {
return male;
}
else if (sex == "0"){
return female;
}
else {
return null;
}
}
private function getIcon1(data:Object):Class {
if (data.sex == 1) {
return male;
}
else if (data.sex == 0){
return female;
}
else {
return null;
}
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout verticalAlign="middle" horizontalAlign="center" />
</s:layout>
<mx:Image source="{getIcon(listData.label)}"/>
<!--<mx:Image source="{getIcon1(data)}"/>-->
</s:MXAdvancedDataGridItemRenderer>
上面代码使用两个方法获得图片,一个是通过data,一个是listData.label,还是前面说的,data是当前行数据,listData.label是当前单元格文本。最后效果如下图:
追加简单方法:
发现一简单方法,AdvancedDataGrid有个iconFunction属性,类型是function,自己定义一个function返回图标。现在可以删掉defaultLeafIcon,folderOpenIcon,folderClosedIcon,添加iconFunction="getIcon",执行效果和前面一样。
private function getIcon(item:Object):Class {
var source:Class;
// 如果是非叶子节点,则item存在GroupLabel属性,值为节点文字内容
if (item.GroupLabel == "人力") {
source = renli;
}
else if (item.GroupLabel == "研发") {
source = yanfa;
}
else { // 叶子节点时item为当前行数据
if (item.manager == 1) {
source = manager;
}
else if (item.manager == 0) {
source = employee;
}
}
return source;
}
下图为debug模式下,item对象数据内容: