【问题标题】:Flex 4.6 Optimizing View appearance ContentCache VS override data for Mobile AppFlex 4.6 优化视图外观 ContentCache VS 覆盖移动应用程序的数据
【发布时间】:2014-08-15 16:29:20
【问题描述】:

我在这篇文章http://www.adobe.com/devnet/flex/articles/flex-mobile-performance-checklist.html 中读到,我不应该在creationComplete 处理程序中初始化视图的外观。相反,我应该在重写的数据设置器中更改视图的外观。

文章中的部分是:

覆盖数据设置器,而不是使用绑定或在 creationComplete 处理程序中初始化视图的外观

1-首先,我想知道我是否做对了以下操作:

//My code is loading a set of images and adding them in a View. 
//On creationComplete of the View I am adding the images in case this is the first time          
//the view is shown. In case the view has been already accessed I use the data:  

   protected function view1_creationCompleteHandler(event:FlexEvent):void
        {
            if(!data) //On first creation of the view I create the data object
            {
                data = new Object();
                data.imageArray = new Array(); //set an array that will cache my images.
                for(var i:int = 0; i<36;i++)
                {
                    var img:Image = new Image();
                    img.source = 'assets/0'+i.toString()+'.png';
                    container.addElement(img);
                    (data.imageArray as Array).push(img);//Override the data for next time!
                }
            }
            else//Next time use the save images
            {
                for(var ix:int = 0; ix<(data.imageArray as Array).length;ix++)
                {
                    container.addElement((data.imageArray as Array)[ix]);
                }
            }
        }

如果我这样做正确,我想知道哪种方法最好。上面的一个,或者我要展示的下一个,它使用图像 contentLoader 并通过 ContentCache 启用缓存和排队:

  protected function view1_creationCompleteHandler(event:FlexEvent):void
        {
            {
                for(var i:int = 0; i<36;i++)
                {
                    var img:Image = new Image();
                    img.contentLoader = ldr;
                    img.contentLoaderGrouping = 'gr1';
                    img.source = 'assets/0'+i.toString()+'.png';
                    container.addElement(img);
                }

        }

<fx:Declarations>
    <s:ContentCache id="ldr" enableQueueing="true"
                    maxActiveRequests="1" maxCacheEntries="36"/>
</fx:Declarations>

另外,如果有人能告诉我 contentLoaderGrouping 的用途。我会很感激。 非常感谢!!!

PS:顺便说一下,这两种方法都有效。第一种方法是即时的,而第二种方法以非常流畅的方式显示添加的图像,实际上产生了很酷的效果。

【问题讨论】:

    标签: image apache-flex mobile flex4 flex4.5


    【解决方案1】:

    两者都没有。建议的重点是不要在创建完成后更改显示列表,这需要额外的更新周期。相反,当您将视图推送到堆栈上时,您应该inject the data property,并在设置器中启动您的更改。使用 ContentCache 与它无关(如果使用不当,有时会导致额外的开销)。

    override public function set data(value:Object):void
    {
        super.data = value;
    
        //this was poorly optimized, so I made it
        //a little better...
    
        var imageArray:Array = (value == null || value.imageArray == null)?
            null : value.imageArray as Array;
    
        if(imageArray == null) //On first creation of the view I create the data object
        {
            imageArray = new Array(36); //set an array that will cache my images.
            for(var i:int = 0; i<36;i++)
            {
                var img:Image = new Image();
                img.source = 'assets/0'+i.toString()+'.png';
                container.addElement(img);
                imageArray[i] = img;
            }
    
            super.data = {imageArray:imageArray}
        }
        else//Next time use the save images
        {
            var n:int = imageArray.length;
            for (var j:int = 0; j < n; j++) 
            {
                container.addElement(IVisualElement(imageArray[j]));
            }
        }
    }
    

    编辑

    我弄错了在视图生命周期中何时设置数据属性。

    这是它的工作原理:

    所以你是正确的,此时容器将为空。我打算为你写一个例子,但我无法弄清楚你的最终目标是什么。您将图像存储在数据属性上是否有特定原因?我认为您可能真正想做的是:

    private var _data:Object = {cache: new ContentCache()};
    
    protected function show_clickHandler(event:MouseEvent):void
    {
        this.navigator.pushView(views.MyView, _data);
    }
    

    在视图中...

    <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="MyView">
    
        <fx:Script>
            <![CDATA[
                import spark.components.Image;
                import spark.core.ContentCache;
    
                override protected function createChildren():void
                {
                    super.createChildren();
    
                    //you might want to do a sanity first check to make sure the 
                    //data was passed in correctly...
    
                    var cache:ContentCache = ContentCache(this.data.cache);
    
                    for(var i:int = 0; i < 36; i++)
                    {
                        var img:Image = new Image();
                        img.contentLoader = cache;
                        img.source = 'assets/0' + i.toString() + '.png';
                        container.addElement(img);
                    }
                }
            ]]>
        </fx:Script>
    
        <s:VGroup id="container" />
    
    </s:View>
    

    【讨论】:

    • 清澈如水,非常感谢。问题是容器尚未创建。所以现在的问题是如何将组件添加到容器的创建链中,所以他在创建时添加这些组件,而不是有一个新的更新周期。
    • 我的理解是,MXML 子项的创建发生在初始化之后,在为数据驱动的容器设置数据属性之前。这不是 ViewStack 的情况吗?如果是这样,您可以覆盖 createChildren 并在那里第一次初始化您的数据,如果容器为空,则在数据设置器中尽早返回。
    • 好的,工作得很好。覆盖数据肯定在 createChildren 之前。您说使用 ContentCache 可能会导致额外的开销。如果我在添加的图像上使用它怎么办?那么它会导致开销吗?
    • 就是这样!我没有将图像保存在数据上,而是保存了 ContentCache!这是完美的!平滑的效果来自于 enableQueueing = true;在内容缓存上!顺便说一句,我看到你也在对我的问题发表评论:stackoverflow.com/questions/19939794/…你知道答案吗?
    • 我也有一种情况,我想用组件覆盖数据。我想知道是否有办法通过像这样的简单解决方案来做到这一点。我应该在 SO 上提出一个问题吗?然后我会在这里评论问题的链接并删除这些 cmets。只是因为 SO 中没有办法直接向用户提问。如果你知道答案,你会感兴趣吗?再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多