FlowLayout – a Spark Custom Layout Example
I’ve been working on the Flex SDK team for more than a year now, primarily playing with the Spark layouts. One of the new Spark features is the “assignable layouts”. The stock layouts have been separated into their own classes and the containers can be assigned different layouts at run-time. This modularization allows anyone to create their own cool custom layouts and use them with any of the Spark containers.
I want to show how easy it is to create a custom Spark layout. I’ve chosen a flow layout example where all the elements are arranged horizontally, wrapping to the next row when the width limit of the container is reached. For simplicity I’m going to assume that all elements are of equal height.
Update: Check out part 2 of the article here.
Step 1 – Simple List Application with a Stock TileLayout
For starter, let’s get a simple application going with a Spark List with a few items. I’m going to add a slider that controls the width of the List. By default the List’s layout is the VerticalLayout, but I’m going to switch it to the stock TileLayout just to contrast it with the FlowLayout that I’m going to put together further below.
And the source code:
Step 2 – A Custom Layout Skeleton Class
Next step is creating the skeleton for the custom layout. I’ll create a new AS class FlowLayout.as, and since it is a custom layout, it must subclass LayoutBase. The LayoutBase provides a lot of default functionality, but the most important methods I need to override are updateDisplayList() and measure().
- updateDisplayList() is called by the container to size and arrange the container’s elements.
- measure() is called to calculate the default size of the container based on the container’s elements. I’m not going to override measure(), as the List skin already has default size.
Step 3 – Make Sure It Does Something
Now I’m going to iterate through all of the container’s elements. I’ll access the container through the layout’s “target” property, which is of type GroupBase. To work with the elements I’ll be using the ILayoutElement interface, specifically the following APIs:
- setLayoutBoundsSize(width, height) – where I can also pass in NaN leaving the element to size itself to its preferred size.
- getLayoutBoundsWidth(), getLayoutBoundsHeight() – to get the current bounds of the element.
- setLayoutBoundsPosition(x, y) – to position the element. Coordinates are relative to the container’s origin.
Before delving into too much coding, let’s just size every element to it’s preferred size, stagger them vertically by 10 pixels each and setup the List to use the the new FlowLayout.
And the source code:
Final Step – Finish the FlowLayout
And now let’s finish the FlowLayout – I want to arrange elements left to right, space them by 10 pixels, and move the elements down when there’s not enough space to fit in the containerWidth. With a couple of lines I get the final result:
And the final code looks like this:
Hope you enjoyed it!
Download the source files here.