Posted by: Dennis | July 20, 2007

Liquid Layout for Flash Components

Recently I had to develop a photo gallery in flash. I have had many challenges since I decided to use a combination of 2 design patterns, the “road” was overall quite bumpy but I managed to find solutions to all the problems and I decided to share some of them.

Now, according to wikipedia the term of liquid layout actually refers to controlling the appearance of the elements on screen, mostly in web browsers. What I want to show you is controlling the layout of your component whether it is used as a Flash CS3 component or a standalone Flex ActionScript Application.

Google showed me only a few good results and most of them where AS2 solutions:
http://www.jamesor.com/2006/10/12/creating-liquid-guis-with-flash-part-3/
http://www.tutorio.com/tutorial/liquid-flash-layout

My solution isn’t the best nor the worst, it’s just something I found easy to understand and use. The main idea is to break down the appearance of your components in several elements, each defined by it’s own class. So, consider the simplest example of a photo gallery with 3 elements – a thumbnail bar, a navigation panel and an area for the big image (detail from now on). For that we’ll need 4 classes – 1 for each element (Detail, Navigation and ThumbnailBar) and another one to wrap them all together (PhotoGallery). In terms of Model View Controller design pattern, the 3 visual elements will act as views and the PhotoGallery class will act as the controller.

The end result will look like this: (note that it’s not an actual photo gallery, implementation of this kind of functionality is beyond the scope of the project)

Liquid Layout Test

Here is the complete source of the project. I have used Flex Builder 3 Beta to build it.

I have described the steps to create a simple CS3 components here so I’ll just go on with the description of the classes. All the classes have a similar structure – a couple of properties and some methods:
– init() – handles some initialization
– createChildren() – creates instances of visual objects and adds them to the display list
– draw() – draws and arranges the visual objects

Now, if you are interested only in using it as a Flash CS3 component, you should check out lltest.fla and notice the 2 symbols in the library. The linkage properties for lltest symbol (lltest stands for liquid layout test) show that it’s base class is PhotoGallery.as, so this is your main class. If you are to use it as an ActionScript project in Flex, you need to open LiquidLayouts.as file. This is the class that creates the photo gallery (PG). Use the setSize method to set the PG’s size. As I have mentioned in the post about building flash cs3 components, your main class needs to define a public setSize method in order to see live preview happen, which means that both, the Flash IDE and your the LiquidLayouts class use the same method to resize and redraw the photo gallery.

Among the properties of the PhotoGallery class there are 2 public variables: _navigationSize and _thumbBarSize – these come with some meta tags which will make those 2 properties show up in the property inspector of the component in the Flash IDE (only if used as a component). The properties specify the size (well, the height actually) of the navigation and thumbnail bars. The height of the detail area will becalculated from total height minus the sum the other two:

_detail.setSize(_width, _height - (_navigationSize + _thumbBarSize));

As mentioned earlier, ThumbnailBar, Navigation and Detail classes have pretty much the same structure. It would have been easier to create a generic class having the common behavior and make our view classes extend it. But for the sake of an easier understanding of the project I decided not to shorten it. So each view class has a background and a textfield that shows the class’ name and dimensions. Whenever you resize the component it will show you the new width and height of each element.Finally, if you are using flex, you can set the desired size for the photo gallery and see the end result, or if you want to use it as a Flash CS3 component, export the lltest symbol to a SWC file, open a new AS3 file in Flash, reload the components panel and drag and drop the newly created component

I hope this is a good starting point for those who were searching for some information related to this matter.


Responses

  1. Again, very nice tutorial. By the way, i’m trying to set XML data using AS3. I have the flash movie getting the xml data, however, i can’t get it into a List or Combox. Don’t understand why. The worst thing, is, if a make a simple copy/paste of the components examples from the flash help, simple don’t work. I get lot’s of errors using the AS3 help examples. Isn’t it strange????

    Cya,
    CP

  2. […] It’s really a nice tutorial. Check it here. […]

  3. Obviously when you find something in the help system you expect it to work 100%, but the thing is that the documentation and development teams often don’t communicate very well ( the company I am working at is developing a big product as well, and unfortunately this is the way it SOMETIMES goes) and you end up in an infinite loop of checking over and over again what could you have possibly done wrong.

    C ya
    Dennis

  4. hi, here i’m again. could you pls check the follwoing code and help me by saying what am i doing wrong???
    ================================
    import fl.controls.*;
    import fl.controls.List;
    import fl.data.DataProvider;
    import fl.events.ComponentEvent;

    var xmlLoader:URLLoader = new URLLoader();
    var xmlData:XML = new XML();

    xmlLoader.addEventListener(Event.COMPLETE, LoadXML);

    xmlLoader.load(new URLRequest(“XML.xml”));

    function LoadXML(e:Event):void {

    xmlData = new XML(e.target.data);
    ParseBooks(xmlData);

    }

    function ParseBooks(bookInput:XML):void {

    trace(“XML Output”);
    trace(“————————“);

    var bookChildren:XMLList = bookInput.Book.children();

    for each (var bookInfo:XML in bookChildren) {

    if (bookInfo.name() == “author”) {
    my_lst.dataProvider = new DataProvider(bookInfo);

    trace(bookInfo);
    }

    }

    }
    ===============================
    the trace gives me what i want, but the list i have on the stage, don’t!!!

    I apreciate very much if you say something…

    brgds,
    cp

  5. Ok, i got it. i/o of using the my_lst.dataProvider = new DataProvider(bookInfo);
    I just need to use:
    my_lst.addItem ({label:bookInfo, data:booInfo});

    This way, the List component will load all the data.

    I will make a tutorial with this, what do you think?

    Brgds,
    CP

  6. sounds good man! 🙂
    i’m working on a new article myself right now, stay tuned

    Regards,
    Dennis

  7. Ok, i’ve published my 1st tutorial. have a look!!!

    brgds,
    carlos

  8. This is exactly what I expected to find out after reading the title o.us poetry. Thanks for informative article

  9. I found your postings concerning Flash Components and Actionscript quite helpful.

    What I cannot find — anywhere — is an explanation of how to use the Flash Components without buying into the Flash CS3 IDE product.

    For all the work that I do, the rule is to develop the solution only with the free SDK tools. There are helpful tutorials showing how to build a ‘minimal Flex application’ in actionscript. That technique — compile an mxml file that just initiates the ‘framework’ and then calls your Actionscript class on ‘ApplicatioinComplete’ already adds so much overhead to the .swf that you probably think it is not worth it to try to develop such a solution. But for those of us who cannot afford to license FlexBuilder or Flash CS3, it is worthwhile to have a command-line-compiler ability to build rich applications.

    Using such a technique, however, as soon as I try to new: new Button() in Actionscript, I end up with runtime errors. If there is a way to do this, one of your tutorials would be very much appreciated.

  10. This very tutorial was supposed to show you how to build your own components from scratch.
    If you want to use the built-in components of Flash IDE, you will need to import the component class and all the classes related to it (the ones it sublcasses).

  11. hi, here i’m again. could you pls check the follwoing code and help me by saying what am i doing wrong???
    ================================
    import fl.controls.*;
    import fl.controls.List;
    import fl.data.DataProvider;
    import fl.events.ComponentEvent;

    var xmlLoader:URLLoader = new URLLoader();
    var xmlData:XML = new XML();

    xmlLoader.addEventListener(Event.COMPLETE, LoadXML);

    xmlLoader.load(new URLRequest(”XML.xml”));

    function LoadXML(e:Event):void {

    xmlData = new XML(e.target.data);
    ParseBooks(xmlData);

    }

    function ParseBooks(bookInput:XML):void {

    trace(”XML Output”);
    trace(”————————”);

    var bookChildren:XMLList = bookInput.Book.children();

    for each (var bookInfo:XML in bookChildren) {

    if (bookInfo.name() == “author”) {
    my_lst.dataProvider = new DataProvider(bookInfo);

    trace(bookInfo);
    }

    }

    }
    ===============================
    the trace gives me what i want, but the list i have on the stage, don’t!!!

    I apreciate very much if you say something…

    brgds,
    cp


Leave a reply to cpinho Cancel reply

Categories