You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Layout in FlexJS works a bit differently than in the current Flex SDK.  If you don’t care how it currently works skip ahead to the “FlexJS Layout" section.

The current Flex SDK used a 3-phase, optionally frame-delayed validation mechanism.  Two phases were top-down, one phase was bottom up.  The idea was to handle any change anywhere.  Also percentages were defined as a percentage of non-fixed area in a container.  Just about every object that didn’t have both explicit width got measured because measurements helped define the minimum sizes for things with percentage widths and heights.

This system worked well, but had some annoying issues:

  • Folks were often surprised that things didn’t shrink as expected because of the minimum size calculation for things with percentage sizes
  • You could get into “invalidation/validation loops” where the size of things would compute to be different on each layout pass
  • Time was spent measuring things and often those measurements weren’t used
  • Time was spent setting up event listeners for changes that never got used.

When looking into a layout system for FlexJS, the above were considered, as well as:

  • There is no frame mechanism in the browser.  If you change a display property it shows up right away
  • Percentages in the browser/CSS work differently.  They are a simple calculation on the parent’s size.

FlexJS Layout

FlexJS layout recognizes 3 scenarios:
  1. The child is sized by the parent
  2. The component is sized by its content
  3. The component has explicitly set width AND height.

If the component has only an explicitly set width but not height and vice versa, then the component falls into scenario 1 or 2 based on whether the unspecified dimension has a percentage set on it or not.

Another, more subtle principle, is that width is slightly more important than height.  That’s the way browsers seem to work, so if a choice has to be made, the layout will try to determine the width before the height.

Unlike the current Flex SDK, percentages are a strict percentage of the parent’s size.  No attempt is made to figure out what things can be shrunk or stretched.  This saves having to loop through the children twice: once to figure out how much room there is, and a second to shrink or stretch things.

And unlike the current Flex SDK, a parent does not watch its children’s display properties for changes, so if the height and/or width of some child object changes, the parent and its parent's may not re-layout.  You may have to dispatch a “layoutNeeded” event or use an MXML tag to cause the dispatching of a “layoutNeeded” event.  If we start to see common scenarios where everyone is setting up these update events, we may build them in somehow.  For example, the Image and ImageButton components force a layout in their parents when the image content arrives since that is a common pattern.

This fits with the FlexJS  “just-in-time” instead of “just-in-case” philosophy.  In the dozens of containers and components in FlexJSStore, only 3 “layoutNeeded” events are required.

So when does a component get laid out?

It depends.  Components that don’t have any percentage or explicit dimensions, including width and height CSS styles, or both ”left" and “right" CSS styles, or both “top” and “bottom” CSS styles are considered to be in category 2 and sized when the set of children changes.  When setting up from MXML, all of the children are added then a single childrenAdded event is dispatched to kick off the layout.  When using AS APIs, the childrenAdded event is dispatched as children are added.  You can suppress the event if you are changing lots of children if you remember to dispatch the event yourself when done.

Children who have both an explicitly set width and height are also laid out when the children are added.

All other children theoretically have at least one dimension that is relative to the parent’s size.  At the beginning of the application, the default Application class sets the initial view to the size of the Flash Player or Browser window.  This generally causes a single top-down pass through all of the children that weren’t already sized to content or sized explicitly.

When done, if a dimension is sized to content, the layout sets the size of that dimension.

Note: As of May 18, 2015, lots of the views and layouts aren’t handling all three scenarios.  Also, most views and layouts are not listening for childrenRemoved events.

  • No labels