我在flex中创建了一个项目渲染器火花列表,但我想在列表中添加新行而不是之后调用函数。我在渲染列表中获取一个数据对象,我正在获取要在列表中显示的数据类型,即。文字或图片。因此,在列表中添加新数据时,我希望在渲染列表中调用函数来检查接收的数据类型,然后它将创建并添加图像元素或文本元素。所以主要的问题是如何获得一个在添加数据时调用的函数。我已经尝试了像datachange这样的事件并添加但是当我们滚动列表时它们会一遍又一遍地调用函数但是我希望函数只在添加数据时调用一次而不是在病毒之后调用。下面是渲染器列表代码,也许你会更好地了解我想要做的事情:
<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/mx"
autoDrawBackground="true" dataChange="test_add()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
public function test_add() : void {
Alert.show("type="+data.msg_type);
if(data.msg_type=="text"){
//code to create and add new text element to list_row//
}
if(data.msg_type=="image"){
//code to create and add new image element to list_row//
}
}
]]>
</fx:Script>
<s:Group id="list_row" width="100%" verticalAlign="middle" verticalCenter="0">
</s:Group>
</s:ItemRenderer>
任何帮助都将受到高度赞赏。 感谢
答案 0 :(得分:1)
据我所知,您显示的代码最简单的解决方案是使用两个独立的ItemRenderers:一个渲染文本,另一个渲染图像。您可以使用SkinnableDataContainer#itemRendererFunction属性而不是itemRenderer
来执行此操作。
具有新属性的列表:
<s:List id="myList" dataProvider="{dp}"
itemRendererFunction="getItemRenderer" />
为正确的ItemRenderer返回工厂的函数。
private function getItemRenderer(item:Object):IFactory {
if (item.msg_type == "text")
return new ClassFactory(MyTextItemRenderer);
if (item.msg_type == "image")
return new ClassFactory(MyImageItemRenderer);
}
在这两个不同的ItemRenderers中,您可以根据需要显示数据。
编辑:为什么每次滚动都会触发dataChange
事件。
实际上,你所描述的方法没有任何问题,尽管我认为itemRendererFunction
方法可以更好地分离关注点。我可以告诉您,只需将List#useVirtualLayout属性设置为false
即可关闭不需要的行为。
<s:List id="myList" dataProvider="{dp}"
itemRenderer="myItemRenderer" useVirtualLayout="false" />
虽然这会做你要求的(即只创建一次ItemRenderers),但这不是一个好建议。默认情况下,此属性设置为true
是有充分理由的。
当使用虚拟布局时,项目渲染器仅在需要时创建,即当它们进入视图并需要显示给用户时。这允许您加载数千个项目而不会丢失性能。
假设您加载了1000个值对象:不占用大量内存或CPU。但现在你要渲染它们。如果您不使用虚拟布局,则会预先为所有这些创建项目渲染器,这意味着数千个图形元素和数千个事件侦听器(多少完全取决于您的设置)。现在 会在慢速计算机上损害性能。
如果您只使用虚拟布局 - 比如说 - 将立即创建10个项目渲染器。如果用户向下滚动,则将创建下一个10,并且从视图中消失的那些将被删除并最终被垃圾收集。所以你看到:你最初认为对性能有害的东西,实际上是一件好事。
所以我建议你不要做我刚才告诉你的事。除非您知道您的列表中的项目数量非常有限,否则您可能会遇到这种情况。然后你可以考虑不使用虚拟布局。