无法使自定义布局中的动画正常工作
Can't get animation in Custom layout to work
我想创建一个布局,我可以在其中为我的项目设置动画。因此,当在我的列表上设置数据提供者时,列表的布局会将这些项目动画化到屏幕上。
所以我创建了一个 CustomLayout 并添加了一个 update() 函数。
在 updateDisplayList 中,项目被追踪得很好。
但是在我想要制作动画的 update() 函数中,即使我跟踪 layoutTarget 的 numElement 我得到四个项目,项目也被跟踪为 null!如果我在主应用程序中设置 _dataProvider 一两秒后使用 setTimeout,然后在 ListLayout 中调用 update(),那么跟踪工作正常。所以我的问题是,如何确保在项目实际可用时调用 update() 为项目设置动画?
主应用程序:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:custom="*"
creationComplete="handleCreationComplete()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var _dataProvider:ArrayCollection;
public function set dataProvider(value:ArrayCollection):void
{
_dataProvider = value;
listLayout.update();
}
private function handleCreationComplete():void
{
var arr:Array = new Array( { label:"1" }, { label:"2" }, { label:"3" }, { label:"4" } );
dataProvider = new ArrayCollection(arr);
}
]]>
</fx:Script>
<s:List id="list"
dataProvider="{ _dataProvider }"
labelField="label">
<s:layout>
<custom:ListLayout id="listLayout" />
</s:layout>
</s:List>
</s:WindowedApplication>
列表布局:
package
{
import mx.core.ILayoutElement;
import spark.components.supportClasses.GroupBase;
import spark.layouts.supportClasses.LayoutBase;
/**
* ...
* @author
*/
public class ListLayout extends LayoutBase
{
public function update():void
{
var layoutTarget:GroupBase = target;
//layoutTarget.autoLayout = false;
var count:int = layoutTarget.numElements;
trace(count); //traces 4
for (var i:int = 0; i < count; i++)
{
var item:ILayoutElement = useVirtualLayout ? layoutTarget.getVirtualElementAt(i) : layoutTarget.getElementAt(i);
trace(item); //traces null
}
}
override public function updateDisplayList(width:Number, height:Number):void
{
super.updateDisplayList(width, height);
var layoutTarget:GroupBase = target;
var count:int = layoutTarget.numElements;
for (var i:int = 0; i < count; i++)
{
var item:ILayoutElement = useVirtualLayout ? layoutTarget.getVirtualElementAt(i) : layoutTarget.getElementAt(i);
trace(item); //traces out the item
}
}
}
}
在 listLayout 上调用 update 之前,您需要 validate 您的“list" 以确保所有元素都可用。所以在 set dataProvider function 中添加一行 list.validateNow() 如下:
public function set dataProvider(value:ArrayCollection):void
{
_dataProvider = value;
list.validateNow();
listLayout.update();
}
我想创建一个布局,我可以在其中为我的项目设置动画。因此,当在我的列表上设置数据提供者时,列表的布局会将这些项目动画化到屏幕上。
所以我创建了一个 CustomLayout 并添加了一个 update() 函数。
在 updateDisplayList 中,项目被追踪得很好。
但是在我想要制作动画的 update() 函数中,即使我跟踪 layoutTarget 的 numElement 我得到四个项目,项目也被跟踪为 null!如果我在主应用程序中设置 _dataProvider 一两秒后使用 setTimeout,然后在 ListLayout 中调用 update(),那么跟踪工作正常。所以我的问题是,如何确保在项目实际可用时调用 update() 为项目设置动画?
主应用程序:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:custom="*"
creationComplete="handleCreationComplete()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var _dataProvider:ArrayCollection;
public function set dataProvider(value:ArrayCollection):void
{
_dataProvider = value;
listLayout.update();
}
private function handleCreationComplete():void
{
var arr:Array = new Array( { label:"1" }, { label:"2" }, { label:"3" }, { label:"4" } );
dataProvider = new ArrayCollection(arr);
}
]]>
</fx:Script>
<s:List id="list"
dataProvider="{ _dataProvider }"
labelField="label">
<s:layout>
<custom:ListLayout id="listLayout" />
</s:layout>
</s:List>
</s:WindowedApplication>
列表布局:
package
{
import mx.core.ILayoutElement;
import spark.components.supportClasses.GroupBase;
import spark.layouts.supportClasses.LayoutBase;
/**
* ...
* @author
*/
public class ListLayout extends LayoutBase
{
public function update():void
{
var layoutTarget:GroupBase = target;
//layoutTarget.autoLayout = false;
var count:int = layoutTarget.numElements;
trace(count); //traces 4
for (var i:int = 0; i < count; i++)
{
var item:ILayoutElement = useVirtualLayout ? layoutTarget.getVirtualElementAt(i) : layoutTarget.getElementAt(i);
trace(item); //traces null
}
}
override public function updateDisplayList(width:Number, height:Number):void
{
super.updateDisplayList(width, height);
var layoutTarget:GroupBase = target;
var count:int = layoutTarget.numElements;
for (var i:int = 0; i < count; i++)
{
var item:ILayoutElement = useVirtualLayout ? layoutTarget.getVirtualElementAt(i) : layoutTarget.getElementAt(i);
trace(item); //traces out the item
}
}
}
}
在 listLayout 上调用 update 之前,您需要 validate 您的“list" 以确保所有元素都可用。所以在 set dataProvider function 中添加一行 list.validateNow() 如下:
public function set dataProvider(value:ArrayCollection):void
{
_dataProvider = value;
list.validateNow();
listLayout.update();
}