无法使自定义布局中的动画正常工作

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();
}