views:

32

answers:

1

Hi,

I'm having some problems figuring out how to organise data pulled off XML in cells within a container. I'm sure this should be a basic thing in AS3, but my head's fried.. can anyone help?

Basically an array if fed to callThumbs() which iterates through it and compares the entries with preloaded XML _my_images. If match is found, it's sent to processXML which loads all relevant info and loads a .jpg thumbnail. All this is then fed to createCell which creates a specific cell with position values depending on x_counter and y_counter values (4 cells in a row) and adds the cell into a container _container_mc.

The Problem: This all works fine and looks fine, the problem is that the cells within the container do not display in descending order. They are in random order, probably because some of the .jpg's takes longer to load etc. How do I easily organise the cells within the container in descending order by the XML .id value? Or how do I tell Flash to wait till the thumbnail and data is loaded and the cell created and added?

Thanks guys, would really appreciate all the help!

PJ

//Flash (AS3)       

       function callThumbs(_my_results:Array):void {   // selector = 1 for specific items, 2 for search items

            var _thumb_url:XML;

            for (var r:Number=0; r < _my_results.length; r++) { // iterate through results vector, compare with _my_images XML .id

                for (var i:Number=0; i < _my_images.length(); i++) {

                    if (_my_images[i][email protected]() == _my_results[r]) {

                        _thumb_url=_my_images[i];

                        processXML(_thumb_url, i);

                    }

                }
            }

        } // End callThumbs


        function processXML(imageXML:XML, num:Number) { // Processes XML data and loads .jpg thumbnail

            var _thumb_loader=new Loader();

            _thumb_loader.load(new URLRequest("thumbs/thumb_sm/" + imageXML.@id + "_st.jpg"));
            _thumb_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,thumbLoaded);
            _thumb_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, urlNotFound);

            var id:XMLList = new XMLList;
            id = imageXML.@id;
            var description:XMLList = new XMLList;
            description = imageXML.@description;

            function urlNotFound(event:IOErrorEvent):void {
                trace("The image URL '" + String(imageXML.@id) + "' was not found.");
            }

            function thumbLoaded(e:Event):void {
                    var imageLoader:Loader = Loader(e.target.loader);
                    var bm:Bitmap = Bitmap(imageLoader.content);

                    createCell(bm, id, description, num);
                    adjustFooterBar(); // Adjust bottom footer
            }


        } // End processXML



        private function createCell(_image:Bitmap, _id, _description:String, _position):void { // Creates a cell with data, add to container

            var _cell_mc = new CellTitle();         

            _cell_mc.initCell(_image, _id, _description, _position, x_counter, y_counter);

            if (x_counter+1 < 4) {
                x_counter++;
            } else {
                x_counter = 0;
                y_counter++;
            }

            _container_mc.addChild(_cell_mc); // movieclip container

        } // End createCell
+1  A: 

In order to tell flash to wait for each thumbnail, you will have to wait for each one to load before loading the next. You should be able to easily modify your code to handle this. The code below may need some changes, I am more just trying to illustrate my point.

(AS3)
   // create these outside of the functions so they can be updated/used by both
   var i:Number = 0;
   var totalResults:Number = _my_results.length;

   // start loading the first thumbnail
   callThumbs(0);

   function callThumbs(resIndex:Number):void { 

        var _thumb_url:XML;
        var result = _my_results[resIndex];

        for (var n:Number = 0; n < _my_images.length(); i++) {

            if (_my_images[n][email protected]() == result) {

                _thumb_url = _my_images[n];

                processXML(_thumb_url, n);

                /**
                 * break here because we don't want to do another iteration
                 * the complete handler for the thumbnail loader will determine if this function
                 * is to be called again.
                 */
                break;
            }

        }

    } // End callThumbs


    function processXML(imageXML:XML, num:Number) {

        var _thumb_loader = new Loader();

        _thumb_loader.load(new URLRequest("thumbs/thumb_sm/" + imageXML.@id + "_st.jpg"));
        _thumb_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,thumbLoaded);
        _thumb_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, urlNotFound);

        var id:XMLList = new XMLList;
        id = imageXML.@id;
        var description:XMLList = new XMLList;
        description = imageXML.@description;

        function urlNotFound(event:IOErrorEvent):void {
            trace("The image URL '" + String(imageXML.@id) + "' was not found.");
        }

        function thumbLoaded(e:Event):void {
                var imageLoader:Loader = Loader(e.target.loader);
                var bm:Bitmap = Bitmap(imageLoader.content);

                createCell(bm, id, description, num);
                adjustFooterBar(); // Adjust bottom footer

            // determine if there is another thumbnail to be loaded
            if (i < totalResults) {
                i++;
                callThumbs(i);
            }

        }


    } // End processXML



    private function createCell(_image:Bitmap, _id, _description:String, _position):void { // Creates a cell with data, add to container

        var _cell_mc = new CellTitle();         

        _cell_mc.initCell(_image, _id, _description, _position, x_counter, y_counter);

        if (x_counter+1 < 4) {
            x_counter++;
        } else {
            x_counter = 0;
            y_counter++;
        }

        _container_mc.addChild(_cell_mc); // movieclip container

    } // End createCell

Also, just out of curiosity, is this being done on the timeline?

Chris Gutierrez
Hmm, I'm trying to figure out how to get this done with irregular numbers (i.e. if the array entered has numbers like 1023, 2021, 3432, etc). I guess I can use the array index no.?This is done in `Main.as` which is extends the `MovieClip`.
PJ Palomaki
Maybe if I do `_my_results.reverse();` and `_my_results.pop();` - this would give me the first entry (lowest number) which I can use to compare with the XML.. how would I do this in the code? Or is this even possible?
PJ Palomaki
Doh! Didn't realise that you were doing this already with the Array index no.! Sorry. I'll have a go and see what happens...
PJ Palomaki
If you have an array then the keys are sequential. The example I gave assumes that the _my_results variable is an array (numerically indexed). am I correct in saying that the _my_results variable looks something like _my_results = ["1023", "2021", "3432"]; ?
Chris Gutierrez
That's right, something similar.
PJ Palomaki
Okay! Finally got it working. Had to move the `if (i < totalResults) { i++; callThumbs(i); }` at the end of the `createCell` function, otherwise it didn't have any effect, thumbs were still in wrong order. But now it works fine, albeit a bit slow loading the thumbnails, I guess since it loads one thumb at a time, not multiple at the same time...Thanks Chris, really appreciate the help!PJ
PJ Palomaki
Thanks again Chris, really helpful comments. I do have one problem though - the thumbnails are loaded by clicking a category button, the problem is that if you click the button fast twice, it loads duplicate thumbnails of some of the items in the category or if I click two different category buttons fast it loads thumbnails from the first category into the second one. Also the rest of the thumbnails are again out of order. I'm not really sure where the problem is, any ideas?
PJ Palomaki
One thing you might want to do is disable all the buttons when one is clicked, then re-enable them once the cells are done being rendered. You may also want to keep a state variable so that if the same button is clicked, it doesn't try to re-render the same cells. If you have classes for these buttons, I would add an enable and disable method that adds and removes the event listeners. Hope this makes sense.
Chris Gutierrez
Had way too many buttons (a big menu and loads of categories) so decided to cheat and created an invisible menu-sized button which I toggled `.visible = false;` whenever a loop was running so the user couldn't interact with the menu. Dirty, but it works!
PJ Palomaki