With all of the Flex developers that I have worked with, I have seen some confusion about creating custom components. They get creating a simple MXML component with some ActionScript, sometimes using a code behind to perform more complex ActionScript magic. The confusion I see happening though is they are usually unaware of how the Flex Framework works with components and that there is already a flow in which Flex creates, displays, and updates components. My own mea culpa here is I was one of those developers. I don’t want people going through the same frustration I experienced. So I am putting together this series of articles to help developers understand the Flex Component lifecycle, and how to use that lifecycle to make your development easier, more efficient, and less frustrating. (You know, when things aren’t drawn on screen when you want them to, or appearing in places that you didn’t expect.)
This article is for Flex 3, since Flex 4 will be changing this lifecycle in a fairly significant manner. When I know more about that, I will post a new set of articles relating to Flex 4 and it’s way of doing things. If you can’t wait for me to finish the rest of the articles, you can read more on the Adobe documentation on advanced component development.
All Flex components, from UIComponent on up, implement several key methods that enable them to be used by the Flex framework to create themselves and their children, measure themselves, position their children, and a whole host of other things. Most custom UI components will be created by extending existing Flex UI components. Here I will give you the basics for those methods, and some things that you can do with them, and several things your shouldn’t do with them. In later articles I will unpack these concepts to give you more detail and code samples.
There are several key methods in custom UI components that you as a developer should at least be aware of, and will be using in most of your custom component development.
- layoutChrome (I haven’t ever used this one, so any feedback on it would be appreciated)
The one common thread with these methods here is they should never be called manually. They are all called automatically by the Flex Framework at specific times, either at component instantiation, or when certain conditions are true. (Such as when size, properties, or display list is marked invalid.) All of these methods are also overridden methods from the Flex UI components you are extending.
There are also several methods that will be called automatically, and also called when certain actions need to be performed. These things signal the component framework to do it’s magic.
createChildren is called shortly after the component is instantiated, and is used to create the initial children of the component, and adding them to the display list. This isn’t to say more children won’t be created later. It is used to create the initial children of the component, and should be used for only that. You should never need to, and never should, call createChildren yourself. It is only called the once by the framework when the component is instantiated, and to count on that functionality, don’t call it yourself.
measure is called by the Flex framework when invalidateSize() is called on the component. If the size of the component is set explicitly, however, then measure will never be called. measure is used to set the component’s preferred minimum size based on the size and layout of it’s children. The properties set by measure include: measuredWidth, measuredHeight, measuredMinWidth, measuredMinHeight, these values are then used by the component’s parent to calculate how big it should be, and then on up the chain. Once all of these are calculated, the cycle starts its way down and starts to set the sizes that components should be. The parent sets the component’s actual size, despite what it’s preferred size may be. There is no guarantee the parent will use those measurements to size the component. Generally, if the component needs to be smaller, the parent will adhere to the measuredMinWidth and measuredMinHeight, but use scrollbars to give it enough space.
updateDisplayList is called often. It is called when your component’s child invalidates its size, it is called by your component’s parent when it needs to resize. It is called whenever your parent needs to resize you, and it is called when your children need to resize. It is called automatically, and even more so than createChildren, never, never call it manually. Call invalidateProperties(), invalidateSize(), or invalidateDisplayList() instead. That way the Flex framework will automatically call updateDisplayList, and you won’t run into race conditions by calling it out of order, or start off an unnecessary cascade of intense updating of all the components on the screen. updateDisplayList sizes and positions your component’s children, and that is all. If you need to change any other properties of your children, they should be done in other methods.
I will cover invalidateProperties(), invalidateSize(), and invalidateDisplayList() in a later article. They are called for specific reasons, and do specific things in the framework. For those reasons they deserve their own writeup.
The commitProperties method is called as part of the component life cycle after invalidateProperties(); is invoked. This is where you will assign the values that were changed by your setters being called. Your setter methods will have calls to invalidateProperties() to mark the component as needing to call commitProperties in its next lifecycle pass. Setters may also call invalidateDisplayList() as well, if the property being set will change the size of the component or one of it’s children, or would add a child to the UI component.
I would talk about this one, but I haven’t ever used it. So check out the Adobe docs on this one.
So that is the basics. Next time I will unpack custom component creation in more detail, and give you code examples for the things I discussed here.
I need to thank several people and sources for teaching me about custom components and the component life cycle before I sign off here.
- Michael Labriola – especially his Facts of (Component) Life presentation that I saw at Flex Camp Chicago 2009
- Adobe’s documentation – it’s a fairly decent starting place, but I would listen to Mike’s presentation first since he breaks it down better.
- Thomas Fowler – for going over my initial posting and suggesting some good edits.
- Jeff Tapper – for finding a huge error in where I placed a paragraph.
- There are more, but I don’t have the links right now. I will post them in later articles.
Edit: In the previous version of this article, I misplaced a paragraph during editing. invalidateProperties(), invalidateSize(), and invalidateDisplayList() can all be called manually. None of them should be overriden. As you can see now, the paragraph should have gone under the other methods (createChildren, measure, updateDisplayList, etc.). Thanks Jeff for that catch.