Flex FlowBox Container

Posted on November 5, 2007 by Tony Fendall.
Categories: Adobe, Components, Flex.

flowboxDemoSource

In a recent project of mine, I needed a container which would lay its child components out in a horizontal manner like an HBox, but unlike an HBox, it needed to wrap the child components into a new row when they exceeded the available width.  If the available height was exceeded, the container should then grow downwards if the height property has not been set to a constrained value.  If the height is constrained, then scrollbars should appear. I found two other flow layout Flex containers on the Internet, but both had issues with scrollbars appearing before they were required, and strange behavior after several rows of children were added.  I also investigated using the Flex Tile component, but this has some bugs in the measure function which meant I couldn’t achieve the growing behavior I required.  After spending much time trying to rework the code I had found, I decided to build my own flow layout container from scratch which I call the FlowBox.

The container works by creating several child HBox containers and adding the children of this container to the sub-container until it is full. When the sub-container is full, a new one is created to manage the next row.  This approach has the advantage that I don’t have to deal with all the complicated layout code that the HBox container already implements, and with a bit of fiddling around I can almost completely hide these sub-containers from the outside.

Features
My focus in building this component was to make the behavior as similar to the existing Box control as possible.  Some of the key features include:

  • Supports all of the properties and styles that the Flex Box container supports including alignment and child spacing
  • Supports both horizontal and vertical directions
  • Can add child components from both action script and MXML
  • Full support for child manipulation including adding, removing and swapping children by item and by index
  • Available under the MIT license

Known Issues
There are two known issues with the component at the time of release.

The first is that the numChildren property of the container is not implemented correctly.  In order to make this function work as it should I would have to work with code inside the mx_internal namespace.  When I attempted this I got large numbers of errors, I eventually decided that this wasn’t going to be a good option. Particularly with Flex 3 coming right around the corner.  The simple work around is to instead use

flowBox.getChildren().length

Incidentally, this component has not been tested with Flex 3 at all, but in theory there’s no reason why it shouldn’t work.

The second issue, is that I wasn’t able to find a way to stop the add and remove child events firing as the hidden, internal containers are created and removed.  Any event listeners that the component adds to itself fire are triggered too late to stop the events from propagating out. Again, if you have any ideas as to how this could be solved, let me know.

This is my first attempt at releasing a polished, reusable component so your comments and suggestions would be very much appreciated.  This code is released under the MIT license, so feel free to use it in any way that helps you.

DemoSource

Comment on November 6th, 2007.

Take a look at Flexlib, they already have a horizontal flow container:
http://code.google.com/p/flexlib/

Their implementation is a bit cleaner, without the nested HBoxes, but their implementation is/was very difficult to transition over to a Vertical flow (I’ve had to re-write much of the code, and it still doesn’t work in all instances yet).

Anyways, Good job! Take a look at flexlib, and if you have code to contribute, contact them asap!

Comment on November 6th, 2007.

Thanks Dusty,

I tried the FlowBox component in flexlib, but the version I got from there seemed to have problems with the layout after more than four rows of children were added.

The code in there was very intelligent, but too complex for me to be able to figure out what was going wrong with it. Thus I thought a simpler approach might be easier.

I will be looking to submit this component to flexlib and others, but I think I’m going to try and make a more polished version two first.

Trackback on November 8th, 2007.

Flex FlowBox Container

Flex FlowBox Container ? Tony ???????,????????Container?????,???????:??????????????,??????????????

?? | ??
Popular…

Comment on November 22nd, 2007.

Hey hi Tony, i think Flex Framework should include some of the features you mentioned, i’ve worked a lot with Panels and they messed up things even when applying Styles, anyway this component looks great! :-D

Pat
Comment on November 23rd, 2007.

Nice work.
Playing with the demo, I found that if there the vertical scrollbar appears, the horizontal scrollbar appeared as well.

Comment on November 30th, 2007.

This occurs as a result of the way the Flex ScrollControlBase class determines what scrollbars should appear. If a vertical scrollbar appears, then the horizontal one also appears to allow for the 22 pixels of space that the vertical scrollbar takes up.

You can work around this problem, but for the purposes of the demo, I didn’t bother.

Comment on December 30th, 2007.

Best job – congratulations. All loks great.

Comment on January 7th, 2008.

After all the effort of getting this component to work, it looks like I might have been better to simply use a Flex Toolbar, and this supports a flowing layout already:
http://blog.flexexamples.com/2008/01/06/creating-a-resizing-toolbar-in-flex/

I’ll look into it more deeply when I get a chance.

Barry Becker
Comment on August 19th, 2008.

I modified the demo so that the Panel containing the FlowBox has 100% width. I would like the elements within the FlowBox to relayout as I resize the browser window. However, I noticed, that the relayout only works as expected as the browser window gets wider. When I reduce the width, the panel does not reduce its width. Instead a horizontal scrollbar appears.
The only way I found to workaround this problem is to make the relayoutChildren method public and call it from the application when its resize vent fires. Is there a way to encapsulate this behavior within the control so the client does not have to make this extra effort when resizing?

Jørgen
Comment on September 2nd, 2008.

Hi!

Great component, but I tried to use it like an image grid (images added as childs and loaded in a while loop). Since the images hadn’t finished loading when the grid was built, it miscalculated the “width” and “height” of the children. The result was all images collected on one row with horz scrollbar.

I suppose the best way is to set the height and width manually on the children before I add them?

Comment on September 2nd, 2008.

You could set the width and height on the children before you add them. If you know what the width and height should be, then this is the easiest option.

If you don’t know the width and height before adding the components what you will need to do is go into the FlowBox class, and find all of the add/remove child functions. Whenever a child is added, you need to attach a resize listener to that child, and when a child resizes, you need to call the relayoutChildren() function to recompute the layout. You will need to remember to remove the resize listener whenever a child is removed also.

Hope that helps.

Anuj Sharma
Comment on September 4th, 2008.

Hi Tony
Great Job. I have some questions. I am making a video gallery in Flex 3.0 (using AS 3.0).Can i use your component for laying out resizeable videos in the flow box. I like to code to put videos in your container and so as soon as user resizes i like other videos to arrange of its own. Do you think does this component handle this. Please let me know.
Thanks a lot.
Best Regards
Anuj

Anuj Sharma
Comment on September 4th, 2008.

Hi Tony
I used my resize able images in Flow Control but as soon as i start resizing it, and it crosses the width of the container it starts generating horizontal scroller in spite of my turning off the scroll policy. This happens within the row. Now is it possible to turn off the scoll policy of the Flowbox within the row of the flowbox.
Please let me know.
Your help will be highly appreciated
Thanks
Anuj

Anuj Sharma
Comment on September 5th, 2008.

Hi Tony
I tried to rearrange the layout of the images upon resizing and tried to get rid of scroll-bars but its not working. I got your suggestion but i could not figure out how should i code it. So far i developed few prototypes but this is kind of new project for me. Please help me in figuring out this. Any help and pseudo-code will be appreciated.
Thanks a lot Tony
Anuj

Joe
Comment on October 12th, 2008.

Yeah, isn’t Flexlib lame. A bunch of bigwigs in the Flex community get together and release something like it’s halfway official, and then everything in it is half-baked. I mean what kind of lame flow component doesn’t support vertical? While yours is by no means perfect, it sure beats theirs, and its imperfections can be dealt with reasonably in real-world applications.

I couldn’t get it to flow correctly when I added to it in an ActionScript class’s set dataProvider method. (Everything ended up in a single VBox with scrollbars turned on.) So, I just re-instantiated it instead of adding to it, and everything worked beautifully.

Thanks a lot for posting this.

Yui
Comment on December 6th, 2008.

Hello,
This is really cool, but i was wondering if it’s possible to middle-align the boxes within each row.

Nice work, otherwise :)

cupuyc
Comment on May 27th, 2009.

Has anybody tried it with repeater?

It renders repeater content outside of FlowBox for me.