问一个UIComponent自定义容器的问题

sunsetfreedom 2010-11-28 11:22:47
由于用VBox之类的容器来做ItemRenderer基类容器加载很慢。。。所以在网上查了查有高手说用UIComponent直接当容器,这样比较快,所以就找了一个代码

package renderers
{
import mx.controls.AdvancedDataGrid;
import mx.controls.Image;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.IDataRenderer;
import mx.core.UIComponent;
import mx.events.FlexEvent;

public class MyItemRenderer extends UIComponent implements IListItemRenderer, IDropInListItemRenderer,IDataRenderer
{
public function MyItemRenderer()
{
super();
}
/*
* 创建子组件,并设置样式及可见性等
*/
override protected function createChildren():void
{

super.createChildren();
// 增加子组件
}
private var _data:Object;

[Bindable("dataChange")]
public function get data():Object
{ //trace("data:"+_data);
return _data;
}

/*
* 在这个方法中调用invalidateProperties(),是为了在适当的时候调用commitProperties()
* 进行数据显示设置以及组件的可见性。
* 派发事件,并由get data()监听,是为了数据源的绑定。
*/
public function set data(value:Object):void
{
trace("setData"+_data);
_data=value;
//img=new Image();
trace("value:"+_data.thumbnailImage);

dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
invalidateProperties();
}

/*
* 在这个方法中进行数据设置。当然,也可以在set data()中进行,不过可能会有不妥的时候吧
*/
override protected function commitProperties():void
{
//trace("commitProperties");
super.commitProperties();
// 获取列设置信息
//var field:String = (listData as DataGridListData).dataField;
// lbl.text = data[field];
}

/*
* 在这个方法中对子元素进行定位和设置大小,默认大小为0×0
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{

//trace("updateDisplayList");
super.updateDisplayList(unscaledWidth, unscaledHeight);
trace("宽度:"+unscaledWidth);

//lbl.move(0, 0);
//lbl.setActualSize(unscaledWidth, unscaledHeight);
}

/*
*
*/
override protected function measure():void
{
//trace("measure");
super.measure();
// 如果AdvancedDataGrid的variableRowHeight="true"应该实现该方法,以提供合适的宽高
}

private var _listData:BaseListData;

public function get listData():BaseListData
{
return _listData;
}

public function set listData(value:BaseListData):void
{
_listData=value;
trace("listData:"+_listData);
}
}
}

继承UIComponent的容器,但是在mxml直接使用就会报错:

<mx:HorizontalList id="horizontalList2" visible="true"
labelField="label"
iconField="thumbnailImage"
dataProvider="{arr}"
columnCount="4"
rowCount="1"
variableRowHeight = "true"
horizontalScrollPolicy="on" x="7" y="26" width="450" height="155">
<mx:itemRenderer>
<fx:Component>
<map:MyItemRenderer>
<mx:Image source="{data.thumbnailImage}"/>
</map:MyItemRenderer>
</fx:Component>
</mx:itemRenderer>
</mx:HorizontalList>

报错信息:由于“Image”声明未实现“mx.core.IUIComponent”,它必须包含在 <Declarations> 标签中。
然后我就自己定义一个MyitemRenderer:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/02/15/creating-a-simple-image-gallery-with-the-flex-horizontallist-control/ -->
<map:MyItemRenderer width="126" height="100" xmlns:map="renderers.*" xmlns:mx="http://www.adobe.com/2006/mxml" >

<mx:Image id="imgg" source="{data.thumbnailImage}" />

<mx:Label id="l1" text="{data.label}" />

</map:MyItemRenderer>

mxml代码换成:

<mx:HorizontalList id="horizontalList2" visible="true"
labelField="label"
iconField="thumbnailImage"
dataProvider="{arr}"
columnCount="4"
rowCount="1" itemRenderer="MyitemRenderer"
variableRowHeight = "true"
horizontalScrollPolicy="on" x="7" y="26" width="450" height="155">
</mx:HorizontalList>

这样就能正常运行,但是图片根本渲染不出来,我debug出来image.source确实已经绑定上了数据源,但是没有呈现出来,网上也查了不少时间了,发现对于这个自定itemRenderer UIComponent容器只有这一个例子,还是官网上翻译过来的...哪位高人写过类似的东西,麻烦指点一下我哪里写错了??
我的开发环境是:flex 4
多谢各位了
...全文
511 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
x87343133x 2011-04-13
  • 打赏
  • 举报
回复
楼主也解决了我遇到的问题,太感谢了
sunsetfreedom 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 herowach 的回复:]
明明是个container用途,却要用UIComponent实现,给我的感觉是想法偏离实际,结果反而会适得其反
[/Quote]
呵呵...问题解决了,如果用container的话,效率太慢,所以直接用UIComponent当容器,这样快了很多,我测试的结果也确实快了好多,其实那个类是对的,只不过我没有在UIComponent里面添加image这个元素.
下面是正确的用法:

package MyImage
{

import mx.controls.AdvancedDataGrid;
import mx.controls.Image;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.IDataRenderer;
import mx.core.UIComponent;
import mx.events.FlexEvent;

import spark.components.Scroller;

public class MyItemRenderer2 extends UIComponent implements IListItemRenderer, IDropInListItemRenderer,IDataRenderer
{
private var image:Image;
public function MyItemRenderer2()
{
super();
}
/*
* 创建子组件,并设置样式及可见性等
*/
override protected function createChildren():void
{

super.createChildren();
image = new Image();
addChild(image);
// 增加子组件

}
private var _data:Object;

[Bindable("dataChange")]
public function get data():Object
{ //trace("data:"+_data);
return _data;
}

/*
* 在这个方法中调用invalidateProperties(),是为了在适当的时候调用commitProperties()
* 进行数据显示设置以及组件的可见性。
* 派发事件,并由get data()监听,是为了数据源的绑定。
*/
public function set data(value:Object):void
{
trace("setData"+_data);
_data=value;
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
invalidateProperties();
}

/*
* 在这个方法中进行数据设置。当然,也可以在set data()中进行,不过可能会有不妥的时候吧
*/
override protected function commitProperties():void
{
//trace("commitProperties");
super.commitProperties();

if(_data)
image.source = data.thumbnailImage; // 获取列设置信息
//var field:String = (listData as DataGridListData).dataField;
// lbl.text = data[field];
}

/*
* 在这个方法中对子元素进行定位和设置大小,默认大小为0×0
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{

//trace("updateDisplayList");
super.updateDisplayList(unscaledWidth, unscaledHeight);
trace("宽度:"+unscaledWidth);
//设置子元素的位置和大小,注意:如果没有设置,就不会显示
image.move(0,0);
image.setActualSize(image.contentWidth,image.contentHeight);
//lbl.move(0, 0);
//lbl.setActualSize(unscaledWidth, unscaledHeight);
}

/*
*
*/
override protected function measure():void
{
//trace("measure");
super.measure();
// 如果AdvancedDataGrid的variableRowHeight="true"应该实现该方法,以提供合适的宽高
}

private var _listData:BaseListData;

public function get listData():BaseListData
{
return _listData;
}

public function set listData(value:BaseListData):void
{
_listData=value;
trace("listData:"+_listData);
}
}
}

用法:

<mx:HorizontalList id="horizontalList2" visible="true"
labelField="label"
iconField="thumbnailImage"
dataProvider="{arr}"
columnCount="4"
rowCount="1"
variableRowHeight = "true"
horizontalScrollPolicy="on" x="7" y="26" width="450" height="155">
<mx:itemRenderer>
<fx:Component>
<map:MyItemRenderer2>
</map:MyItemRenderer2>
</fx:Component>
</mx:itemRenderer>
</mx:HorizontalList>


leemiki 2010-11-29
  • 打赏
  • 举报
回复
<HorizontalList dateProvider="{sourceColl}" itemRenderer="mx.controls.Image"/>

sourceColl中存放image的路径
herowach 2010-11-29
  • 打赏
  • 举报
回复
明明是个container用途,却要用UIComponent实现,给我的感觉是想法偏离实际,结果反而会适得其反
sunsetfreedom 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lieri111 的回复:]
楼主你是不是没有new UIComponent就无法载入
[/Quote]
好像不是这个原因吧,MyItemRenderer是一个ItemRenderer容器,不用new UIComponent()吧...
passself 2010-11-28
  • 打赏
  • 举报
回复
楼主你是不是没有new UIComponent就无法载入
sunsetfreedom 2010-11-28
  • 打赏
  • 举报
回复
没有人弄过么???拜托了各位!!!

4,328

社区成员

发帖
与我相关
我的任务
社区描述
多媒体/设计 Flex
社区管理员
  • Flex
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧