by Deepa Subramaniam
Table of contents
8 March 2010
This article assumes a basic familiarity with Flex.
Flex (Download trial)
This article assumes a basic familiarity with Flex.
With the release of Flex 4 comes the introduction of a new skinning and component architecture for Flex user interface components called Spark. Spark offers designers and developers a seamless way to customize the visuals and behaviors of a Flex component in a much more direct and effortless manner. Whereas in prior versions of Flex, developers and designers could heavily style their applications and potentially drop into programmatic or graphical skinning to achieve the look and feel they desired, Spark gives users a more intuitive, declarative, and robust skinning model that lets true creativity come to life. In this article I introduce some of the exciting new capabilities of the Spark architecture and component set shipping with Flex 4. I also highlight some of the other cool capabilities of Spark, such as assignable layouts, a new graphics library, an enhanced states model, and a whole new effects engine. Additionally, I explain how Spark components can interact and live side-by-side with MX (Flex 3 and prior) components.
Spark is the name of the new component skinning architecture as well as component set shipping with Flex 4. The main tenet of the Spark architecture is supported by a skinning model that provides a neat separation of a component’s visual elements from its logic. This separation gives designers and developers more freedom, because the visual elements of a Flex component can be designed in an unfettered manner, independent of the implementation of the logic powering the component. After learning the Spark skinning model, you can build expressive and robust Flex components in a very short amount of time.
Before you dive into more details on the Spark architecture, you may be wondering about the inspiration behind introducing a new skinning and component architecture with Flex 4. The main motivation came from the desire to support the rich workflows enabled by Adobe Flash Catalyst. Flash Catalyst is a designer-friendly tool that looks and feels like any other Adobe Creative Suite tool and is used for building expressive Flex content. The powerful workflows provided by Flash Catalyst (along with integrated workflows across other Adobe Creative Suite tools like Illustrator, Photoshop, and Flash Professional) required a rethinking of the Flex framework to allow for powerful toolability. This was the genesis of Spark.
The core principle driving the Spark architecture is a clean separation of the code comprising the visuals of a component from the code governing the component logic. Because of this separation, every Spark component consists of two classes: a skin class, which is written in declarative MXML, and a component class, which is written in ActionScript. The details of what should be written in the skin class versus the component class and how to associate the two classes together are covered below.
Before I jump into Spark architecture details, I should briefly talk about the component architecture and component set that existed prior to Flex 4, which is called MX (sometimes referred to as Halo). The MX component architecture and component set are still available within Flex 4 and Flash Builder 4. Additionally, Spark and MX components are interoperable. This is because, under-the-covers, Spark components extend the same base class as the MX components: mx.core.UIComponent. Because of this common foundation, Spark components can live within MX containers, Spark containers can contain MX components, and Spark and MX components can live side-by-side in a single Flex application.
Since Spark and MX components share the same base class, the same component lifecycle methods, properties, and events that existed for the MX components apply to Spark components. Thus, the Spark skinning functionality is added atop the MX component lifecycle, and only to the Spark classes that support Spark-style skinning. For example, MX components follow a validation model comprising three key methods:
commitProperties() measure() and updateDisplayList(). Spark components still use these methods, though in a different manner, and skinning related methods and properties are layered atop this MX component lifecycle. To learn more about the MX component lifecycle and how it differs from the Spark component lifecycle, check out my Adobe MAX video, Creating New Components in Flex 3 and Beyond.
Each Spark component consists of two classes: a declarative, MXML-based skin class and an ActionScript component class. The skin class contains everything related to the visual appearance of the Spark component, while the ActionScript class contains everything related to the functional logic of the component. These two classes are associated together via the styling mechanism that has been in place within the framework since the beginning of Flex. However, what exactly is defined within the component class and how the skin class reacts to those definitions is the key secret to the magic of Spark.
Every Spark component class defines three very important elements: the data the component expects, the constituent parts that make up the component, and the states the component can enter and exit. In the corresponding skin class, the skin defines how that data is visually displayed, how the parts are laid out and visualized, and what the component looks like as it enters and exits different states. These three key elements— data, parts, and states—define the skinning contract upon which Spark is founded.
Skin parts are essentially the smaller pieces of a component that get assembled together to build up a fully functional component. For example, the skin parts of a Spark NumericStepper are essentially a Spark TextInput control wired to two Spark Buttons, which act as the up and down buttons in traditional NumericStepper controls. The ActionScript component class defines which skin parts a Spark control may require and it is the responsibility of the corresponding skin class to instantiate and lay out any required skin parts. This interplay between the parts defined by the Spark component and instantiated by the skin class is one cornerstone of the Spark skinning contract.
Similarly, skin states play a key role in the contract between a Spark component and skin class. Skin states define the views a Spark component will enter and exit based on interaction. For example, a Spark Button has up, over, down, and disabled states. The ActionScript component class is responsible for all of the event handling needed to identify when a state change has occurred and ensures the component is put in the right state. The skin class defines how the component looks and behaves as it enters and exits those states. This interplay between the states defined by the Spark component and displayed by the skin class is another cornerstone of the Spark skinning contract.
It’s important to note that the states concept was added to Flex during the Flex 2 timeframe. However, because of the desire to make Spark more powerful in a natural way, the states syntax went through a significant makeover with the Flex 4 release. To learn more about the enhancements made to the states model in Flex 4, check out the Enhanced States Syntax documentation.
Likewise, to learn more about how skin parts, states and, data are defined, as well as walk through code examples of each concept at play, read Introducing Skinning in Flex 4 by Ryan Frishberg.
As you learn more about the new skinning architecture, you will notice that some very valuable features were added to Flex 4 to support the Spark goal of easy and intuitive development and design. In this section, I highlight three of those features: an enhanced effects engine built directly into the Spark foundation, a powerful new metaphor that lets components reuse and reassign layouts, and a graphics library that captures drawing primitives as simple MXML tags.
New in Flex 4 is an enhanced animations engine, which provides improved effects and transitions that can be used by Spark components. With this new animation engine, Flex 4 effects can target arbitrary objects or property types and use new Flash Player 10 features. It was essentially rewritten from the ground up to achieve better fidelity and performance than the prior Flex effect classes. This animation engine can be invoked directly within Spark skin classes through state-based transitions. Alternatively, effects can be directly applied to component parts. Chet Haase has written a series of articles that walk you through creating basic effects, wiring up more complex effects, and invoking effects that show off some of the dazzling capabilities of Flash Player, such as 3D effects and Pixel Bender shaders. For more information, read Effects in Flex 4 Part 1 and Effects in Flex 4 Part 2 as well as the Flex documentation on the new animation engine.
Layout is part of the governance of a skin class, which makes sense since layout is intrinsic to the visuals of any component. One of the cool new features added in Flex 4 is a much more flexible and hearty layout system. The Spark layout system is built atop the foundation laid by the MX layout system. MX concepts like width and height, constraint-based layout, and percentage-based sizing still exist within Flex 4 layouts. However, in addition to these concepts, Flex 4 layouts provide a whole set of new functionality including (but not limited to) APIs for robust 2D and 3D transformations, the ability to easily implement custom layouts, and most importantly, the concept of assignable layout.
Assignable layout boils down to the ability to assign specific layouts to different containers and controls (versus having the layout embedded directly within the definition of the container or control). For example, the MX List control is vertical in nature. To get an MX List that lays out its data elements horizontally or in a tile-like fashion, you would have to instantiate an MX HorizontalList or an MX TileList. With Flex 4 assignable layouts, you can take a Spark List control and assign to it any of the native Flex 4 layouts (such as a vertical, horizontal or tile-like layout) or any custom layout that implements a few specific interfaces. This is an amazingly flexible option that lets you create components with very different layouts all by modifying a single property on the component. You can learn more details about the new layout capabilities in Flex 4, as well as walk through code examples, by reading Evtim Georgiev’s Spark Layouts in Flex 4 article and referring to the Flex documentation on Flex 4 layouts.
One of major new additions in Flex 4 is the introduction of a graphics library, often referred to as MXML Graphics, which includes graphic primitives, grouping containers, and support for complex transformations. The graphic primitives include shapes like Rectangles, Ellipses, and Paths as well as text primitives. You can instantiate these primitives in MXML and you can set properties or define child elements that let you do anything that Flash Player drawing functionality allows. For example, you can define a Rectangle in MXML that is stroked by a linear gradient stroke, filled with a radial gradient fill, has an alpha or filter set on it, and is masked by an opacity mask. Because of the declarative nature of these MXML graphic tags, they are often used within skin files to define the visual elements of a Spark component.
The capabilities of the MXML Graphics library are defined by an interchange format called FXG. This interchange format is used across many Adobe Creative Suite tools, including Adobe Flash Catalyst, Adobe Illustrator, and Adobe Photoshop, to preserve the contents drawn on screen so that they can be imported and edited within your preferred design tool. You can learn more about the technical details of the FXG interchange format (which is essentially a subset of MXML Graphics) by reading the FXG 2.0 technical specification as well as the Flex documentation on MXML Graphics and the FXG Interchange Format.
Flex 4 currently offers a broad range of Spark components. Subsequent releases of Flex will provide more Spark controls in order to achieve parity with the MX component set. To learn more about the skin parts, states, and base classes of each individual Spark component or control, please refer to the ActionScript 3.0 Reference for the Adobe Flash Platform documentation or the Spark container and Spark list-based controls chapters in the Flex documentation.
All spark containers support assignable layout.
- Group – A non-skinnable container class in Flex 4, which can contain visual children such as UIComponents, Flex components created in Adobe Flash Professional, or graphic elements.
- DataGroup – A non-skinnable container class in Flex 4, which can contain only non-visual data items as children. DataGroup containers support item renderer generation (a visual element that converts a data item into something that is displayable) as well as virtualization of their elements.
- SkinnableContainer – A skinnable version of a Group.
- SkinnableDataContainer – A skinnable version of a DataGroup.
- Application – The top-level, skinnable container for browser-based Flex applications (as opposed to AIR applications, which use the Spark WindowedApplication container described below).
- BorderContainer – A skinnable container that supports CSS styles for border and background filling (similar to the border and background styles supported by MX containers).
- Panel – A skinnable container that supports a title bar, caption, and border.
- TitleWindow – A skinnable container similar to a Panel that supports a close button and moveable area. A TitleWindow is meant to be popped up as a pop-up window via the PopUpManager.
- Window – A skinnable component that can be used as a top-level application window in an Adobe AIR application.
- WindowedApplication – A skinnable component that defines the application container in an Adobe AIR application.
- Button – A skinnable, rectangular button.
- CheckBox – A skinnable component that consists of a label and a box supporting a checkmark.
- RadioButton – A skinnable component used for identifying a single choice across a group of mutually exclusive radio buttons.
- ScrollBar – A skinnable component for controlling how much data is displayed in a given content area.
- Slider – A skinnable component that allows for values to be selected by dragging a thumb in between the two end points of a slider track.
- Spinner – A skinnable component consisting of an up and down button used to select a value from an ordered set.
- NumericStepper – A skinnable component that is essentially a Spark Spinner control wired to a Spark TextInput control and allows for the selecting and editing of a numeric value.
- Label – A non-skinnable control that displays a single line of uniformly formatted text.
- RichText – A non-skinnable control that can display multiple lines of richly formatted text with support for embedded images.
- RichEditableText – A non-skinnable control that can be used to display, scroll, edit, and select multiple lines of richly formatted text.
- TextArea – A skinnable control that allows for the display and editing of multiple lines of richly formatted text.
- TextInput – A skinnable control that allows for the display and editing of a single line of uniformly formatted text.
- List – A skinnable component that displays data items. It supports item renderer generation, single and multiple selection, drag-and-drop operation, virtualization, and assignable layout.
- DropDownList – A skinnable component that lets a user chose a value from a list of values that is dropped open.
- ComboBox – A skinnable component that is essentially a Spark DropDownList with editable functionality.
- ButtonBar – A skinnable component that supports a single button being chosen out of a navigator-like group of buttons.
- TabBar – A skinnable component that supports choosing a single tab from a navigator-like group of tabs.
- Scroller – A skinnable component that defines a scrollable view and can support vertical and horizontal scrollbars.
- VideoPlayer – A skinnable component that supports the playback of video media and is built atop the Open Source Media Framework.
Where to go from here
Now that you have learned more about the powerful new Spark skinning architecture and component set available in Flex 4, you’re ready to venture out and customize an existing Spark component or build your own Spark component from scratch. The capabilities of the Spark architecture enable you to easily build Flex applications and components that look unlike any Flex content you may have seen prior to Flex 4.
If you are looking for further information, there is a technical whitepaper on the Spark Component Architecture, which goes into more detail regarding the Spark skinning contract, Spark base classes, and component and container classes. Additionally, details on individual Flex 4 features can be found in the Flex 4 documentation, which contains very useful technical information and code samples for a better understanding of how the features are used in practice. And finally, the Tour de Flex reference application showcases many Flex capabilities and is replete with running examples and code snippets that can be easily pasted into Flash Builder. Now go and design and develop Flex components and applications to your heart’s content!