Skinning in Flex 4

  • 18,912 views
Uploaded on

Presentation at Adobe Developer Summit 2009 India at Chennai and Hyderabad. …

Presentation at Adobe Developer Summit 2009 India at Chennai and Hyderabad.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • very good
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
18,912
On Slideshare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
453
Comments
1
Likes
8

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • Not gonna talk about styling, though skinning is the next step after styling. Skinning is the process of changing the appearance of a component by modifying or replacing its visual elements. These elements can be made up of bitmap images, SWF files, or class files that contain drawing methods that define vector images. Skins can define the entire appearance, or only a part of the appearance, of a component in various states. Change visual appearance - Stlyling – css etc. Example – humans have skin, but have different color of skins.
  • Styling - When you want to customize the appearance of a Flex component, you have two options. One is to tweak the default appearance of the component using styling . Each Flex component has an extensive set of style properties you can set to change its appearance: the roundness of corners, the colors used for fill gradients, the font, color, and size of text, and so on. If you find that you can’t achieve the look that you want purely through styling, or if you just want to draw the appearance rather than tweaking a bunch of knobs, then you can use Adobe design tools to draw graphical skins for your components. Skins allow you to completely customize the appearance of a component.
  • The default skins for the up, over, and down states appear as follows(in the image) Other controls have similar states with associated skins. For example, RadioButton controls, which are subclasses of Button, also have up, down, and over skins. The ComboBox control has skins the define the appearance of the control when it is in the disabled, down, and over states.
  • This slide really sums up how skinning is done in flex 3. Stateful skins – define a skin that defines each state of the component programmatic skins – ActionScript or MXML classes graphical skins – bitmap images or swf files
  • Although embedding styling declarations directly into MXML files or ActionScript code is a powerful concept, but such techniques provide limited interaction between designers and Flex developers. And so full-fledged, customized look-and-feels for a Flex application ( are ) were still hard to achieve. For example, you want to create a button that performs a cross-fade from the Up state to the Over state as you roll mouse over it. In Flex 3, this is not a built-in behavior of the Button component. To implement the design requirement, you would have to first create a new programmatic skin that handles the different state changes; the skin is also responsible for managing the tween to create the fade. This is by no means a simple feat to accomplish, and for a developer, this could take anywhere from a few hours to a few days depending on your understanding of the component structure and how complex the design requirements are. Because Flex 3 requires a lot of code to solve a rather simple design requirement, we have seen the process of skinning components become one of the most time-consuming processes of Flex development. The further the design pushes away from the default UI behavior, the more time and development investment is required. This also means that as design requirements change, a project involves much more than simply updating the UI. Often you have to spend more time in the code to meet the design change.
  • Because Flex 3 requires a lot of code to solve a rather simple design requirement, we have seen the process of skinning components become one of the most time-consuming processes of Flex development. The further the design pushes away from the default UI behavior, the more time and development investment is required. This also means that as design requirements change, a project involves much more than simply updating the UI. Often you have to spend more time in the code to meet the design change.
  • Monkey Patching to achieve desired changes to the component view.
  • Separate data, logic and behavior from visuals, states, animation and layout
  • text field, icon, background
  • Copy MXML from default Button Skin Add two tags to create two icons Adjust position/size of icons and label All MXML! Extend viewIconForPhase & duplicate logic for new icon ~100 lines Extend layoutContents to position/size new icon and position/size existing components so nothing overlaps Requires ActionScript knowledge and understanding of Button component
  • Single, consistent mechanism for all skins - skinning a Button is the same as skinning a List item. Formal mechanism for skinning composite components through skin parts. Declarative control of all visual aspects of components so it can be easily created and manipulated by tools
  • A user is creating an application and wants to change the look and feel of an Button. Without having to write any ActionScript code, he creates a new ButtonSkin to use within his application. Because this skin file is MXML, a tool can be used to create/modify it; also, it's easy for a designer to come up with one or modify an existing one to suit their needs.
  • A developer is creating a custom component that he wants to sell to other customers. However, he wants the user to be able to modify the look and feel of the component. By extending SkinnableComponent and hooking into the SkinnableComponent lifecycle, the developer ensures skinning will be easy for the users.
  • A designer is looking to pocket some extra money on the side. He decides to create a set of skins for Flex components and packages them up in a SWC that he sells to other Flex application developers. The application developers change some CSS and start using the new skins.
  • Each component contains four conceptual pieces: model, skin, controller, and view-specific logic. The model contains the properties and business logic for the component. For example, a Range model has properties for minimumValue, maximumValue, stepSize, etc., and methods for stepping by a line or a page. The model does not contain any visual or behavioral information. The skin defines the visual elements of the component. The controller is the interface between the skin and the model. It has several key functions: * Defining the component behavior. For example, the Button controller has all of the mouse event handling logic. * Defining the visual states of the component. * Defining the parts of a component. For example, an FxScrollBar controller has 4 parts: up arrow, down arrow, thumb, and track. The view-specific logic helps position and size the different parts of a skin. For example, FxHScrollBar and FxVScrollBar have different view-specific logic which determine the position of the thumb. To make a circular scrollbar one would have to override this logic. A skinnable component is one whose skin can be changed during authoring or at runtime.
  • Putting the pieces together * The model and controller are typically written in ActionScript * Inheritance should be used to separate the model from the controller. In the framework, we try to do this; however, the distinction between model and controller can sometimes be unclear, especially when the model is a UI element. This is not a hard rule that one always needs to follow, but it is a recommendation when possible. * The skin is typically written in MXML. * The view-specific logic could be written in the skin file; however, most of the time the logic should be put into the component itself, or a subclass of the component, because lots of people need that logic and it makes skinning easier. An example of this is FxScrollBar->FxHScrollBar or FxScrollBar->FxVScrollBar. * For skinnable components, skins are associated through CSS
  • To establish association between a component and its skin , we need some sort of an agreement or contract
  • http://www.adobe.com/devnet/flex/articles/flex4_skinning.html
  • Adding graphics to your Flex applications can make them more attractive and usable. In many cases, you might want to add graphics that are vector-based, and not import images that don’t scale well. You can create vector based graphics in Flex by using one of the following APIs: FXG MXML Graphics FXG is a declarative syntax for defining static graphics. You typically use a graphics tool such as PhotoShop or Illustrator to export an FXG document, and then use the FXG document as a component in your Flex application. FXG components are highly optimized. MXML graphics, on the other hand, are a collection of classes that you use to define interactive graphics. You typically write MXML graphics code in Flash Builder. You can add interactivity to MXML graphics code because they use classes in the Flex SDK that are subclasses of GraphicElement. The result is not as optimized as FXG. The amount of interactivity when using FXG and MXML graphics is different. If you use MXML graphics, the tags are mapped to their ActionScript equivalent classes. You can reference the MXML graphic elements and have greater control over them. If you use FGX, then you cannot reference instances of objects within the FXG document from the application or other components. In addition, you cannot add MXML code to it, nor can you add ActionScript. FXG and MXML graphics define the following:Graphics and text primitives Fills, strokes, gradients, and bitmaps Support for filters, masks, alphas, and blend modes FXG and MXML graphics share very similar syntax. For example, in FXG, you can define a rectangle with the <Rect> element. In MXML graphics, you use the <s:Rect> tag. Most FXG elements have MXML graphics equivalents. FXG and MXML graphics do not share the same namespace. MXML graphics use the MXML namespace of the containing document. In most cases, this is the Spark namespace. FXG uses its own namespace.
  • http://www.adobe.com/devnet/flex/articles/flex4_skinning.html
  • States in Flex 4 are awesome Declare your states with a ‘State’ tag Describe ‘alternate views’ of your markup Change values, bindings, event handlers Include and exclude components as easily as setting visibility Unscoped entries specify the ‘default’ for all states States can be grouped into State Groups - see Flex documentation for more info <fx:Reparent> tag to move children between states WARNING: Use NEW STATES in 2009 documents – 2006 still supports legacy states.
  • push method means taking a property from the component and stuffing it into the appropriate skin slot. On the other hand, if the skin asked the host component what the property value was, that would be the pull method.

Transcript

  • 1. Skinning in Flex 4 Saurabh Narula http://blog.saurabhnarula.com/ http://twitter.com/saurabhnarula
  • 2. Agenda
    • What is skinning ?
    • Skinning in Flex 3
    • Major Differences in skinning components in Flex 3 and Flex 4
    • Flex 4 Component architecture
    • Skinning in Flex 4
    • States
    • Data
    • Skin Parts
    • FXG
    • CSS changes
    • Containers and Layout
    • Examples
    • Q/A
  • 3. What is skinning ?
  • 4. Styling in Flex 3
  • 5. Styling or Skinning?
  • 6. Example of skinning in flex 3 A Button Control Up over down State Skin Property Down DownSkin over overSkin up upSkin disabled disabledSkin selectedDisabled selectedDisabledSkin selectedDown selectedDownSkin selectedOver selectedOverSkin selectedUp selectedUpSkin
  • 7. 1. Create a Skin (types of skins) graphical skins programmatic skins Stateful skins 2. Assign a skin to a component by style properties (CSS). 3. Set a style property by MXML tag properties, the StyleManager class (runtime), <mx:Style> blocks, or CSS
  • 8. Demo Skinning in Flex 3
  • 9. why a new paradigm of Skinning in Flex 4?
  • 10. Designer – Developer interaction? Full fledged, customized look & feel hard to achieve Expectation of knowledge about how components are structured, should know actionscript As a result ..
  • 11. Skinning becomes time consuming Design requirements change -> more effort to include updates spend more time in the code to meet the design change As a result ..
  • 12. Flex 4!!
  • 13. Components in Flex 3 In Halo, Components were rigid. Hard to Extend. Monkey Patching.
  • 14. Components in Flex 4 Separation of data, logic, behavior from visuals, states, animation and layout Write component logic with no assumption about the appearance and vice versa. M Architecture inside your component C V
  • 15. MVC in a button M label:String, selected:Boolean text field, icon, background mouse handlers, selection logic C V
  • 16. Halo Component V Skin (Background) Extend the view M C V
  • 17. Spark Component V Skin (Entire View) M C
  • 18. Example: Button with Two icons Extend viewIconForPhase Halo Spark Extend layoutContents ActionScript knowledge Copy MXML from default Button Skin Two Image tags Adjust position/size of icons and label Done! - All MXML!
  • 19. Skin Component Relationship Component V Skin (Entire View) Skinning Contract M C
  • 20. Flex 4 Skinning Highlights
    • All visual aspects, including layout controlled by the skin
    • Consistent mechanism
    • Formal mechanism – skinning contract
    • Declarative control – FXG
  • 21. Usage Scenarios - User (developer) A User (developer) wants to change the look and feel of a button Create a button skin in MXML MXML can be generated / modified with the help of a tool No actionscript
  • 22. Usage Scenarios - Developer (creator) A Developer create a custom component that he wants to sell to other customers Extend SkinnableComponent , spark component lifecycle Skinning this component is now easy
  • 23. Usage Scenarios - Designer A Designer wants to earn some extra money Package Skins into SWC and sell Change CSS and make use of these skins
  • 24. Each component contains four conceptual pieces: model, skin, controller, and view-specific logic
  • 25. Block layout for skinnable component Skins are associated through CSS
  • 26. Skinning Contract association between a component and its skin A valid contract contains Skin parts Skin states Host Component
  • 27. Skinning Contract .. The Component Class must .. Assign a skin class Identify the Skin Parts Identify the Skin States The Skin Class must .. Define the Host Component Declare Skin States , and define their appearance Define the appearance of the Skin Parts
  • 28. Demo Skinning contract in a button
  • 29. Skinning Contract ..
  • 30.  
  • 31. SkinPart Lifecycle
  • 32. FXG and MXML Graphics the new interchange format for the Flash Platform
    • Add vector based graphics which scale well
    • FXG and MXML Graphics
    • FXG is a declarative syntax for defining static graphics
    • MXML graphics - collection of classes that you use to define interactive graphics
  • 33. FXG .. use a graphics tool such as PhotoShop or Illustrator to export an FXG document use the FXG document as a component in your Flex application FXG components are highly optimized cannot reference instances of objects within the FXG document from the application or other components Can not add Actionscript or mxml code Example - <Rect>
  • 34. MXML Graphics write MXML graphics code in Flash Builder add interactivity to MXML graphics - they use classes in the Flex SDK that are subclasses of GraphicElement result is not as optimized as FXG MXML graphics, the tags are mapped to their ActionScript equivalent classes More Control over graphic elements Example - <s:Rect>
  • 35. FXG and MXML graphics define the following: Graphics and text primitives Fills, strokes, gradients, and bitmaps Support for filters, masks, alphas, and blend modes
  • 36. FXG FXG FXG FXG FXG Designer - Developer Workflow FXG FXG
  • 37. FXG
    • General path element
    • Shapes like rectangle , Ellipse
    • Fine Control over coordinate system, transformation etc.
    • Scalable Raster effects – filters etc
    • Based on Flash rendering model
    • Graphic elements – Shapes ( composed of strait lines, curves), Text, Raster Images
    • Optimized for flash player
    • Subset of MXML
    • Static – no binding, layout, event handlers, styling, etc
    • compile-time optimization to optimize and compress chunks of FXG content
  • 38. FXG Simple Shape primitives (Rectangles, rounded rects, ellipses, circles) Complex Paths (Linear, Quadratic, and Bezier curve segments) Full range of fills and strokes (solid, transparent, bitmap, linear and radial gradients) Masking, filters, blend modes, and more. (blur, glow, dropshadow, screen, multiply…) Color and 2D transformations (rotate, scale, tint, brighten…) Integrated text, bitmaps
  • 39. Demo Writing a Custom Skinnable component QoutesBoard Component Qoutes Board/Group – A Static Part Qoute – dynamic Part Label Display – dynamic Part Close Button – dynamic part
  • 40. Credits and References http://opensource.adobe.com/wiki/display/flexsdk/Gumbo#Gumbo-DocumentsandSpecifications http://www.slideshare.net/rjowen/flex-4-overview http://weblog.mrinalwadhwa.com/
  • 41. Questions ? Thank you. Saurabh Narula http://blog.saurabhnarula.com/ http://twitter.com/saurabhnarula
  • 42. Reference Slides
    • States
    • Data
    • Skin Parts in Detail
    • Advanced CSS selectors
    • Containers and Layout
  • 43. States
    • <!-- Given the states A,B,C -->
    • <m:states>
      • <m:State name=&quot; A &quot; />
      • <m:State name=&quot; B &quot; />
      • <m:State name=&quot; C &quot; />
    • </m:states>
    • <!-- This button will appear in only states A and B -->
    • <Button label=&quot; Click Me &quot; includeIn=&quot; A, B &quot; />
    • <!-- This button will appear in states A and B -->
    • <Button label=&quot; Button C &quot; excludeFrom=&quot; C &quot; />
    • easy to understand and organized markup
    • States can be grouped into State Groups
    • <fx:Reparent> tag to move children between states
    • use invalidateSkinState() and getCurrentSkinState() inside component.
    • invalidateSkinState() invalidates the skin state and eventually sets the skin's state to whatever getCurrentSkinState() returns.
    • getCurrentSkinState() keep track of current state.
  • 44. States .. (comparison) Flex 3 - addchild equivalent <mx:Application xmlns:mx=&quot; http://www.adobe.com/2006/mxml &quot; layout=&quot; absolute &quot; > <mx:states> <mx:State name=&quot; newCheckbox &quot; > <mx:AddChild relativeTo=&quot; { vbox } &quot; > <mx:CheckBox id=&quot; checkbox &quot; label=&quot; Checkbox &quot; /> </mx:AddChild> </mx:State> <mx:State name=&quot; newTextArea &quot; basedOn=&quot; newCheckBox &quot; > <mx:AddChild relativeTo=&quot; { vbox } &quot; > <mx:TextArea id=&quot; textarea &quot; /> </mx:AddChild> </mx:State> </mx:states> <mx:VBox id=&quot; vbox &quot; > <mx:Button label=&quot; Click &quot; click=&quot;currentState= 'newCheckbox' &quot; /> <mx:Button label=&quot; Click &quot; click=&quot;currentState= 'newTextArea' &quot; /> </mx:VBox> </mx:Application>
  • 45. States .. (comparison) Flex 4 - addchild equivalent <mx:Application xmlns:mx=&quot; library:ns.adobe.com/flex/halo &quot; xmlns:m=&quot; http://ns.adobe.com/mxml/2009 &quot; layout=&quot; absolute &quot; > <m:states> <m:State name=&quot; default &quot; /> <m:State name=&quot; newCheckbox &quot; /> <m:State name=&quot; newTextArea &quot; /> </m:states> <mx:VBox> <mx:Button label=&quot; Click &quot; click=&quot; currentState='newCheckbox' &quot; /> <mx:Button label=&quot; Click &quot; click=&quot; currentState='newTextArea' &quot; /> <mx:CheckBox id=&quot; checkbox &quot; label=&quot; Checkbox &quot; includeIn=&quot; newCheckbox, newTextArea &quot; /> <mx:TextArea id=&quot; textarea &quot; includeIn=&quot; newTextArea &quot; /> </mx:VBox> </mx:Application>
  • 46. States .. (comparison) Flex 3 - child insertion <mx:Application xmlns:mx=&quot; http://www.adobe.com/2006/mxml &quot; layout=&quot; absolute &quot; > <mx:states> <mx:State name=&quot; newTextInput &quot; > <mx:AddChild relativeTo=&quot; { checkbox1 } &quot; position=&quot; after &quot; > <mx:TextInput id=&quot; textinput &quot; /> </mx:AddChild> </mx:State> </mx:states> <mx:VBox id=&quot; vbox &quot; > <mx:CheckBox id=&quot; checkbox1 &quot; label=&quot; One &quot; /> <mx:CheckBox id=&quot; checkbox2 &quot; label=&quot; Two &quot; /> <mx:Button id=&quot; button &quot; label=&quot; Click &quot; click=&quot;currentState= 'newTextInput' &quot; /> </mx:VBox> </mx:Application>
  • 47. States .. (comparison) Flex 4 - child insertion <mx:Application xmlns:mx=&quot; library:ns.adobe.com/flex/halo &quot; xmlns:m=&quot; http://ns.adobe.com/mxml/2009 &quot; layout=&quot; absolute &quot; > <m:states> <m:State name=&quot; default &quot; /> <m:State name=&quot; newTextInput &quot; /> </m:states> <mx:VBox> <mx:CheckBox label=&quot; One &quot; /> <mx:TextInput includeIn=&quot; newTextInput &quot; /> <mx:CheckBox label=&quot; Two &quot; /> <mx:Button id=&quot; button &quot; label=&quot; Click &quot; click=&quot; currentState='newTextInput' &quot; /> </mx:VBox> </mx:Application>
  • 48. States .. (comparison) Flex 3 - A RemoveChild Equivalent <mx:Application xmlns:mx=&quot; http://www.adobe.com/2006/mxml &quot; layout=&quot; absolute &quot; > <mx:states> <mx:State name=&quot; noCheckboxes &quot; > <mx:RemoveChild target=&quot; { checkbox1 } &quot; /> <mx:RemoveChild target=&quot; { checkbox2 } &quot; /> </mx:State> </mx:states> <mx:VBox id=&quot; vbox &quot; > <mx:CheckBox id=&quot; checkbox1 &quot; label=&quot; One &quot; /> <mx:CheckBox id=&quot; checkbox2 &quot; label=&quot; Two &quot; /> <mx:Button id=&quot; button &quot; label=&quot; Click &quot; click=&quot;currentState= 'noCheckboxes' &quot; /> </mx:VBox> </mx:Application>
  • 49. States .. (comparison) Flex 4 - A RemoveChild Equivalent <mx:Application xmlns:mx=&quot; library:ns.adobe.com/flex/halo &quot; xmlns:m=&quot; http://ns.adobe.com/mxml/2009 &quot; layout=&quot; absolute &quot; > <m:states> <m:State name=&quot; default &quot; /> <m:State name=&quot; noCheckboxes &quot; /> </m:states> <mx:VBox id=&quot; vbox &quot; > <mx:CheckBox label=&quot; One &quot; excludeFrom=&quot; noCheckboxes &quot; /> <mx:CheckBox label=&quot; Two &quot; includeIn=&quot; default &quot; /> <!-- Works as above --> <mx:Button id=&quot; button &quot; label=&quot; Click &quot; click=&quot; currentState='noCheckboxes' &quot; /> </mx:VBox> </mx:Application>
  • 50. Data
  • 51. Skin Parts
    • two types of parts : static and dynamic
    • Static parts are instantiated automatically by the skin. There may only be one instance per static part
    • Dynamic parts are instantiated when needed, and there may be more than one instance of it
    • For eg. for a Scrollbar, you have 4 different static parts: track, thumb, upArrow, downArrow
    • [ SkinPart (required= &quot;false&quot; ]
    • public var upButton:Button;
    • By Default all SkinParts are required , you can make them optional by setting required parameter as false , set true to make SkinPart required
    • Dynamic SkinParts – more than one instance of the skin part, accordion can have a dynamic SkinPart as the header for each segment, can be required or optional, variable type is Ifactory.
    • [ SkinPart (type= &quot;spark.components.Button&quot; )]
    • public var headerFactory:Ifactory;
  • 52. Defining Skin Parts on the Skin
    • Within a skin definition, parts are identified by their id attribute, id attribute is used to bind this element to the component part
    • If a required part is not defined by the skin, a runtime error is thrown when the skin is attached to the component.
    • <Skin>
    • <!-- other stuff here... -->
    • <MyCustomThumb id=&quot; thumb &quot; ... />
    • <!-- other stuff here... -->
    • </Skin>
    • Dynamic parts , by convention, live in the Declarations section of the skin file
    • <Skin>
    • <Declarations>
    • <Component id=&quot; headerFactory &quot; >
    • <MyCustomHeaderControl />
    • </Component >
    • <!-- More dynamic part definitions can go here... -->
    • </Declarations>
    • <!-- Static skin elements and parts go here... -->
    • </Skin>
  • 53. Working with Static Parts
    • When loading a skin with static parts, the SkinnableComponent base class is responsible for assigning all static parts from the skin to the declared part variables on the component .
    • Once this assignment is done, the component can simply reference the instance variable directly.
    • The partAdded() method is called when the variable is assigned. This is where behavior is added to the part.
    • The partRemoved() method is called before the skin is unloaded. This is where behavior is removed from the part.
    • override protected function partAdded(partName:String, instance:*): void
    • {
    • super .partAdded(partName, instance);
    • // For static parts we can just compare the instance with the property
    • if (instance == thumb) thumb.addEventListener(...);
    • }
    • override protected function partRemoved(partName:String, instance:*): void {
    • super .partRemoved(partName, instance);
    • if (instance == thumb) thumb.removeEventListener(...);
    • }
  • 54. Working with Dynamic Parts
    • instantiated by using the createDynamicPartInstance() method and removed using the removeDynamicPartInstance() method.
    • The partAdded() and partRemoved() methods are called whenever a dynamic part is added/removed – behaviour is added or removed here.
    • There can be many instance of a dynamic part, call createDynamicPartInstance() to create as many as you want.
    • loadSkin() . unloadSkin() , lifecycle methods – load and unload the skin
  • 55. Working with Deferred Parts
    • parts that are created at some indeterminate time after the skin has been created.
    • Components need to be aware that the partAdded() method may be called long after the skin has been instantiated.
    • An example of a deferred part is one in a TabNavigator that isn't created until the tab is clicked on by the user. When the user clicks on the tab, the part will be created, and through Binding, the SkinnableComponent will become aware of the new part and call partAdded() on it.
    public class MyComponent extends SkinnableComponent { // Declare the &quot;details&quot; part [ SkinPart ] public var details:DetailsPane; override protected function partAdded(partName:String, instance:*): void { super .partAdded(partName, instance); if (partName == &quot;details&quot; ) { // Details part has been created. Attach behaviors here. details.addEventListener(...); details.doSomethingElse(); } } }
  • 56. CSS Changes and Advanced Selectors
  • 57. CSS Changes and Advanced Selectors .. Demo
  • 58. Containers and Layouts Group Lowest level container in Spark framework Supports both UIComponents and GraphicElements Only the bare essentials: Layout (through delegates) Containment Basic Flash player features (transforms, etc.) DataGroup The basis of any “List” based container Anything that uses ItemRenderers In Spark, everything displayable resides in a Group
  • 59. Containers and Layouts ..
  • 60. Containers and Layouts .. layouts have been separated from the containers When a Spark container measure() or updateDisplayList() method is called, the task of measurement and child arrangement is promptly delegated to a Spark layout instance Assignable and custom Layouts All layout classes extend LayoutBase VerticalLayout, HorizontalLayout, TileLayout, BasicLayout (Canvas) Basis of layout for all containers, lists, skins, etc. The goal: clean layout, easy extension, consistent behavior Big difference: layouts can support transforms Even though containers support clipping and scrolling, they don't put up scrollbars automatically like Halo does
  • 61. Containers and Layouts .. Custom Layout Demo