Domanda

I read in this article http://www.adobe.com/devnet/flex/articles/flex-mobile-performance-checklist.html that I should not initialize a View's appearance in a creationComplete handler. Instead, I should change view's appearance in an overridden data setter.

The section in the article is:

Override the data setter instead of using bindings or initializing a View's appearance in a creationComplete handler

1-First, I would like to know if I got this right by doing the following:

//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]);
                }
            }
        }

If I am doing this correctly, I would like to know which approach is best. The above one, or the next one I am going to show which uses the images contentLoader with caching and queuing enabled with a 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>

Also if someone could tell me what is the contentLoaderGrouping for. I would be very grateful. Thanks a lot!!!

PS:By the way both approaches work. The first approach is instant while the second approach shows the images beeing added in a very smooth way which actually gives a cool effect.

È stato utile?

Soluzione

Neither. The point of the suggestion was to NOT alter the displaylist after creationComplete, which requires an additional update cycle. Instead you should inject the data property when you push your view on the stack, and initiate your changes in the setter. Using the ContentCache has nothing to do with it (and can sometimes cause additional overhead if not used correctly).

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

EDIT

I was mistaken about when the data property is set during the view life-cycle.

Here is how it works:

View Life-Cycle Diagram

So you are correct that container would be null at that point. I was going to write up an example for you, but I'm having trouble figuring out what your end goal is here. Is there a specific reason you are storing the images on the data property? I think what you might actually want to do is this:

private var _data:Object = {cache: new ContentCache()};

protected function show_clickHandler(event:MouseEvent):void
{
    this.navigator.pushView(views.MyView, _data);
}

And in the view...

<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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top