Flex Building User Interface Components


Published on

design user interface components in flex is just like any other language. This presentation provides some guidelines as to how such components should be design and implemented with performance in mind.

Published in: Technology
  • good reference for any language ui design
    Are you sure you want to  Yes  No
    Your message goes here
  • In my opinion, this presentation serves as a good starting point in building your custom flex components.
    Are you sure you want to  Yes  No
    Your message goes here
  • Dude you have done a great job putting it together. If you don’t mind I would like to use it on my website http://rishikdhar.com. And if you have time, would you mind updating it to version 3.0 or higher, so all the version comptability stuff is taken care of.
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • A common coding practice is to divide an application into functional units, or modules, where each module performs a discrete task. Dividing your application into modules provides you with many benefits, including the following:Ease of development Different developers or development groups can develop and debug modules independently of each other. Reusability You can reuse modules in different applications so that you do not have to duplicate your work.Maintainability By developing your application in discrete modules, you can isolate and debug errors faster than you could if you developed your application in a single file.
  • Ideally components are placed inside another component or container or document. They fire events and have properties for configuration. As we said earlier components may contain other subcomponents. A point I’m going to stress now and always. Its never recommended to have public methods for components you should always try to introduce events for listening to your component and modify data properties to configure your components. using events and properties allow you to integrate smoothly with the UI model of flex and not create performance issues.
  • Simple Components: are components that standardize the look and feel for another component by extending it.Composite Components: are components that group one or more components together to control their layout using on of flexlayout container(vBox,hBox,canvas,panel)Complex Components: are “complex” , they modify a container, control behaviour and the way it lays its data Nonvisual Components: such as formatters, validator,
  • Constructor is called when you instantiate your component.CreateChildren is for instantiating your subcomponents Commitproperties for reading all assign properties … this may be called more than once Measure doing all measurmentsUpdateDisplaylist layout and drawing
  • Keep in mind , overriding methods is always little bit better than handling events inside a component because IF used correctly they reduce the number rendering cycles
  • Binding calls the setter of the property
  • Recommnedations Check if the value actually changed Create a flag to notify the component that the property changed Invalidate the component so it reapplies the property.
  • 2. Differentiate events from internal methods3. Constructor stuff -> preinitialize createChildren stuff -> initializecommitproperties, measure, updateDisplayList ->render, creationComplete (causing rerendering )
  • Dynamic data driven properties components like those that you don’t need if certain properties are set. Flex calls it when the call to the addChild() ….. That is why it might be called more than once check next slide
  • Recommendation Check if a subcomponent is already instantiated because createChildren might be called more than when
  • invalidateProperties() for deferred calculation, child managementinvalidateSize() for changes to the measured size of a componentinvalidateDisplayList() for changes to the appearance of a component
  • Flex Building User Interface Components

    1. 1. Building User Interface Components<br />FLEX 2.01<br />
    2. 2. In this presentation<br />Component lifecycle and optimization tips<br />Generalizing components <br />Designing component API<br />
    3. 3. Why create Components?<br />Ease of development  <br />Reusability  <br />Maintainability  <br />
    4. 4. What are Components?<br />Owner<br />Events<br />Events<br />Events<br />UI Component<br />subcomponents<br />Data Properties<br />Data Properties<br />Data Properties<br />
    5. 5. MXML vs. AS Flex Components <br />Some basic guidelines include the following: <br /><ul><li>Simple components, it is simpler and faster to create them in MXML.
    6. 6. Composite components that contains other components & the Layout of those other components can be set using one of the Flex layout containers, use MXML.
    7. 7. Complex components, such as to modifying the way a container lays out its children, use ActionScript.
    8. 8. Visual component forinstance creating a subclass from UIComponent, use ActionScript.
    9. 9. Nonvisual component, such as a formatter, validator, or effect, use ActionScript. </li></li></ul><li>Component Lifecycle<br />From birth to death, A Component goes through a defined set of steps:<br />Construction<br />Configuration<br />Attachment<br />Initialization<br />Invalidation<br />Validation<br />Interaction<br />Detachment<br />Garbage Collection<br />Building your prototype is the process of implementing this lifecycle…<br />
    10. 10. Component Lifecycle in FLEX<br />Implementing the lifecycle boils down to these methods:<br />Constructor()<br />createChildren()<br />commitProperties()<br />measure()<br />updateDisplayList()<br />Custom events<br />
    11. 11. Construction<br />MXML-able components must have zero arg constructors<br />Call super()…or the compiler will do it for you.<br />Good place to attach your own event handlers<br />Try to avoid creating children here…for best performance<br />
    12. 12. Construction<br />CONSUMER<br />&lt;local:RandomWalk /&gt;<br />or<br />Varinstance:RandomWalk = newRandomWalk();<br />COMPONENT<br />public function RandomWalk()<br />{<br />super();<br />this.addEventListener(<br />MouseEvent.CLICK,<br />clickHandler);<br />}<br />
    13. 13. Configuration<br />MXML assigns properties before sub-components are attached and initialized (avoids duplicate code execution).<br />Your properties (get, set functions) need to expect that subcomponents haven’t been created yet.<br />Avoid creating performance bottlenecks: make set functions defer work until validation.<br />
    14. 14. Configuration<br />property2<br />property3<br />property1<br />invalidateProperties<br />Properties invalidated?<br />yes<br />commitProperties<br />
    15. 15. Configuration (pattern)<br />CONSUMER<br />…<br />instance.dataProvider = xmlDataSet;<br />instance.width = 600;<br />instance.height = 200;<br />instance.labelText = “hello”;<br />...<br />Or via binding<br />… labelText=“{hello}” width=“600” … dataprovider=“{xmlDataSet}”<br />COMPONENT<br />private var _labelText:String;<br />private var _labelTextDirty;<br />public function set<br />labelText(value:String):void<br />{<br />If (_labelText != value)<br />{<br />_labelText= value;<br />//BAD _label.text = _labelText;<br />_labelTextDirty = true;<br />invalidateProperties(); //invalidation <br />}<br />}<br />
    16. 16. Attachment<br /><ul><li>Most component initialization is deferred until it gets attached to a Parent
    17. 17. Styles may not be initialized until its ancestors get rooted to the displayList()
    18. 18. Parent.addChild(At) calls initialize() method to trigger next phase…you can call this explicitly if necessary</li></ul>Parent<br />addChild (ComponentInstance)<br />Component initialization begins<br />
    19. 19. Startup<br />Trigger preinitialize<br />initialization Phase<br />createChildren()<br />Trigger<br />initialize<br />Validation Phase<br />commitProperties()<br />measure()<br />updateDisplayList()<br />Trigger<br />creationComplete<br />Trigger<br />render<br />
    20. 20. Startup<br />Startup happens in multiple sub-phases:<br />1. ‘preinitialize’ event is dispatched<br />2. createChildren method is called, adds sub-components<br />3. ‘initialize’ event is called – component is fully created<br />4. First validation pass occurs<br />5. ‘creationComplete’ event is fired – component is fully commited, measured, and updated.<br />
    21. 21. Startup<br />1.<br />Parent-&gt; preinitialize<br />Parent-&gt; createChildren<br /> Child-&gt; preinitialize<br /> Child-&gt; createChildren<br />grandChild-&gt; preinitialize<br />grandChild-&gt; createChildren<br />grandChild-&gt; initialize<br /> Child-&gt; initialize<br /> Child2-&gt; preinitialize<br /> Child2-&gt; createChildren<br /> Child2-&gt; initialize<br />Parent-&gt; initialize<br />2.<br />Parent-&gt; commitProperties<br /> Child-&gt; commitProperties<br />grandChild-&gt; commitProperties<br />grandChild-&gt; measure<br /> Child-&gt; measure<br />Parent-&gt; measure<br />3. <br />Parent-&gt; updateDisplayList<br /> Child-&gt; updateDisplayList<br />grandChild-&gt; updateDisplayList<br />4. <br />Parent-&gt; render<br /> Child-&gt; render<br />grandChild-&gt; render<br />grandChild-&gt; creationComplete<br /> Child-&gt; creationComplete<br />Parent-&gt; creationComplete<br />
    22. 22. Initialization : createChildren()<br />Creating children here streamlines startup performance<br />Follow the same pattern MXML uses: create, configure, attach.<br />Flex components give subclasses first-crack at defining subcomponents.<br />Don’t forget to call super.createChildren();<br />Defer creating dynamic and data-driven components to commitProperties();<br />
    23. 23. Initialization : createChildren<br />//example<br />protected varcommitButton:UIComponent;<br />override protected function createChildren():void<br />{<br />if (commitButton == null) //only create once—why ?<br />{<br />commitButton = new Button();<br /> Button(commitButton).label = “OK”;<br />}<br />addChild(commitButton);<br />commitButton.addEventListener(MouseEvent.CLICK, commitHandler);<br />super.createChildren();<br />}<br />
    24. 24. Invalidation<br /> Flex imposes a deferred validation model<br />Aggregate changes, defer work until the last possible moment<br />avoid creating performance traps for your consumers<br />Three main invalidation functions:<br />invalidateProperties()<br />invalidateSize()<br />invalidateDisplayList()<br />
    25. 25. Invalidation<br /> Rules of Thumb:<br />1. Change values immediately<br />2. Dispatch events immediately<br />3. Defer Side-effects and calculations to commitProperties()<br />4. Defer rendering to updateDisplayList()<br />5. Be suspicious of rules of Thumb <br />
    26. 26. Validation : commitProperties<br />Invoked by the framework immediately before measurement and layout<br />Use it to calculate and commit the effects of changes to properties and underlying data<br />Avoid extra work: Use flags to filter what work needs to be done<br />Proper place to destroy and create dynamic subcomponents based on changes to properties or underlying data.<br />
    27. 27. Validation : commitProperties<br />//example<br />override protected function commitProperties():void<br />{<br />if (_cme_datachanged)<br /> { _ cme_datachanged = false; //reset flag<br /> //data change effects applied here <br />}<br />super.commitProperties(); <br />}<br />
    28. 28. Validation : measure<br />Invoked by the framework when a component’s invalidateSize() is called<br />Components calculate their ‘natural’ size based on content and layout rules.<br />Implicitly invoked when component children change size.<br />Don’t count on it: Framework optimizes away unnecessary calls to measure.<br />Quick Tip: start by explicitly sizing your component, and implement this later.<br />
    29. 29. Validation : updateDisplayList<br />Invoked by the framework when a component’s invalidateDisplayList() is called<br />The ‘right’ place to do all of your drawing and layout<br />
    30. 30. Interaction<br />Properties: Talk to your component<br />Events: Listen to your component<br />Public methods: Only in very specific cases where you can not use properties or events to fulfill the need<br />
    31. 31. Interaction: Events<br />Events consist of:<br />Name: A unique (per target) name identifying the type of event<br />Target: the object that dispatched the event<br />Event: An Object containing additional information relevant to the event<br />Handler: the function invoked when the event occurs.<br />
    32. 32. Interaction: Events<br />1. Handling Events<br /> Registering, removing, capture, bubble<br />2. Dispatching Events<br /> Flex’s event system is extensible – you can define the events you need to make your component useful. – more on this later<br />Remember that events will bubble up from your sub-components. If you don’t want that to happen, you need to explicitly stop them from propagating.<br />
    33. 33. How the Flash Player Works?<br />
    34. 34. Other topics<br />Generalizing Components<br />Designing Components<br />
    35. 35. Generalizing Components<br />Three important concepts for generalizing your component<br />SKINNING!<br />STYLING!<br />TEMPLATING!<br />
    36. 36. Generalizing Components<br />Three important concepts for generalizing your component<br />Use Properties to generalize the behavior and data<br />Use Skinning and Styling to generalize the look<br />Use Templating to generalize the content.<br />
    37. 37. Generalizing Component : Templating<br />Instance properties<br />Properties typed as UIComponent can be set in MXML like any other property.<br />Reparenting allows you to embed passed values into your own display tree.<br />Allows you to define complex components with configurable parts<br />public function set thumbnailView(value:UIComponent)<br />{<br /> _thumbnailView = value;<br />addChild(thumbnailView);<br />}<br />
    38. 38. Generalizing Component : Templating<br />2. Item Renderers (Factories)<br />Factories are used to generate multiple child components<br />Data driven components use them to generate renderers for the data<br />Allows you to separate management of the data from displaying the data.<br />Quick Tips:<br />Type your item renderers as IFactory<br />Use the IDataRenderer interface to pass your data to the instances<br />If you have additional data to pass, define a custom interface and test to see if it is supported first.<br />
    39. 39. Generalizing Component : Binding<br />Databinding is there to eliminate boilerplate data routing code<br />&lt;mx:Button enabled=“{randomWalk.selectedItem != null}” /&gt;<br />Any property can be the destination of a binding, but the source needs special Support<br />Good rule of thumb: If you think someone might want to bind to it…make it bindable.<br />
    40. 40. Generalizing Component: Binding<br />Add [Bindable] to your class:<br />[Bindable] public class RandomWalk extends UIComponent { …<br />Makes all public varsbindable<br />Convenience feature for value objects.<br />Add [Bindable] to your property<br />[Bindable] public varselectedItem:Object;<br />[Bindable] public function get selectedItem():Object { …<br />Wraps the variable or property in an autogenerated get/set<br />Good for simple properties.<br />Roll your own event based bindings:<br />[Bindable(event=“selectedItemChange”)] public function get selectedItem():Object { …<br />dispatchEvent(new Event(“selectedItemChange”));<br />Works well for read only and derived properties<br />
    41. 41. Designing you API: base Class?<br />What Base Class should you extend?<br />UIComponent:<br />Base class for all component and containers<br />Gateway to key flex functionality: styles, Containers, invalidation, etc.<br />Best choice for most components<br />Container (and derivatives):<br />Only use if your customers will think of your component as a container<br />Allows developers to specify children in MXML (but there are other ways)<br />Scrolling, clipping, and chrome management for free<br />Other ‘Leaf’ Components<br />Good for minor enhancements and guaranteeing type compatibility<br />Major Functionality changes run the risk of ‘dangling properties’<br />Consider using aggregation instead<br />
    42. 42. Designing your API: MXML schema<br />Remember, Your API defines your MXML schema<br />Specifically:<br />ClassName -&gt; XML Tags Name<br />Package -&gt; XML Namespace<br />Properties -&gt; XML Attributes<br />Complex Properties -&gt; Child Tags<br />
    43. 43. Designing your API: Examples<br />A Few Examples:<br />Choose Properties over Methods<br />Properties can be set from MXML<br /> Avoid write-once properties<br />Anything that can be set in MXML can be bound to.<br />Use value objects for complex and multi-valued properties<br />MXML makes object graphs simple<br />&lt;DataGrid&gt;<br />&lt;columns&gt;<br />&lt;DataGridColumncolumnName=“revenue” width=“30” dataField=“revYr” /&gt;<br />&lt;DataGridColumncolumnName=“profit” width=“30” dataField=“profYr” /&gt;<br />&lt;/columns&gt;<br />&lt;/DataGrid&gt;<br />Use different names for styles, events, and properties.<br />
    44. 44. THANKSQuestions ? <br />