Elevate Developer Efficiency & build GenAI Application with Amazon Q
Deep Dive into Flex Mobile Item Renderers
1. DEEP DIVE into FLEX
MOBILE ITEM RENDERERS
Flex SDK 4.5 (Hero)
www.jasonhanson.com/360flex @jayfour000
2. • Jason Hanson
• twitter @jayfour000
• flexfood.blogspot.com
• www.jasonhanson.com
• Building for Flash Platform since 1999
• Working with Hero SDK since Aug,
2010 (beta)
www.jasonhanson.com/360flex @jayfour000
3. DISCLAIMER
• Intended to be a 300 level session (I’ll
let you judge that for yourself :)
• You should be familiar with the
concept of writing Flex components in
AS3
• Knowledge of the Flex component
lifecycle helpful
• We will be looking at CODE
www.jasonhanson.com/360flex @jayfour000
8. Rendering a List
of Items is Hard
www.jasonhanson.com/360flex @jayfour000
9. Scrolling a List
of Items is Harder
www.jasonhanson.com/360flex @jayfour000
10. Scroll Performance
& User Experience
• Slow or jerky scrolling comes off as an
error in your app
• Makes your app seem sluggish
• Distracting at best
• Causes loss of user at worst
www.jasonhanson.com/360flex @jayfour000
12. Rendering Items is
Expensive
• Look! new data. • commitProperties()
• How big am I? • measure()
• Update display • updateDisplayList()
• > Draw background • > drawBackground()
• > Layout • > layoutContents()
www.jasonhanson.com/360flex @jayfour000
13. Draw Faster &
Draw Less Often
• Regular Spark ItemRenderer just not
fast enough for most mobile devices
• Adobe SDK devs spent months
optimizing List scrolling and mobile
ItemRenderers
• Slightly different approach then
standard Flex
www.jasonhanson.com/360flex @jayfour000
14. What About the
MXML ItemRender.as
• Extends Group
• Has significant overhead
• Encourages data binding (expensive)
• Layouts are expensive
• States add weight
• Very convenient features, but they all
add up to lower performance on
mobile
www.jasonhanson.com/360flex @jayfour000
15. Demo of List on
HTC G2
www.jasonhanson.com/360flex @jayfour000
16. New Classes on Next Slide
(Don’t Panic)
www.jasonhanson.com/360flex @jayfour000
18. StyleableTextField.as
• Lightweight text control that
supports Styles
www.jasonhanson.com/360flex @jayfour000
19. • The StyleableTextField class is a text
primitive for use in ActionScript skins
and item renderers.
• It cannot be used in MXML markup
and is not compatible with effects.
• styleName
• setStyle()
www.jasonhanson.com/360flex @jayfour000
22. • Extends UIComponent
• Limited Style Support
alternatingItemColors, chromeColor, downColor,
focusColor, paddingBottom, paddingTop, rollOverColor,
selectionColor, symbolColor, verticalAlign
• Great for simple text renderers
• Renders the ‘data’ property as a string
• Inherits the labelField and
labelFunction from the s:List
www.jasonhanson.com/360flex @jayfour000
23. IconItemRenderer
• Image and text
www.jasonhanson.com/360flex @jayfour000
25. • Uses ContentCache to cache the ‘icon’
images so that they don’t flash when
scrolled to again
• The ‘decorator’ and ‘iconPlaceholder’
should be an embeded asset for best
performance
• Supports both a ‘label’ and ‘message’
www.jasonhanson.com/360flex @jayfour000
31. Roll Your Own
• Options
• Extend UIComponent
• Extend LabelItemRenderer
• Extend IconItemRenderer
www.jasonhanson.com/360flex @jayfour000
32. • Write the custom component in AS3,
not in MXML
• Look to LabelItemRenderer and
IconItemRenderer for best practices
• Extending UIComponent is more
complicated since you have to
implement IItemRenderer
www.jasonhanson.com/360flex @jayfour000
40. ItemPreviewImageRenderer
(Show Code)
• ItemPreviewImageRenderer.as
• set defaults in constructor
• override createChildren()
• override createLabelDisplay()
• override createMessageDisplay()
• set labelFunction
• set messageFunction
• set iconFunction
• override layoutContents()
• override measure()
www.jasonhanson.com/360flex @jayfour000
41. Renderer
Virtualization
• Ensure useVirtualLayout="true"
• Recycles itemRenderers by setting the
data property to null when off screen
• Saves time on createChildren() calls
• Essential for longs lists of data
• Set to true by default
www.jasonhanson.com/360flex @jayfour000
43. Tips!
• getting style cheaper then setting style
• setElementSize()
is cheaper then setting width / height
• setElementPosition()
is cheaper then setting x / y
• Use ContentCache to prevent image
flicker
www.jasonhanson.com/360flex @jayfour000
Welcome to Deep Dive into Flex Mobile Item Renderers.\n
My name is Jason Hanson. If you are interested in learning more about me, what I do, or have questions after this presentation please feel free contact me via Twitter, my blog, or web site.\nA little about me. I have been building for the Flash Platform since 1999, back when I used FlashScript and really had no idea what I was doing. I have stuck with the platform for the past 10+ years, started working with Flex Builder 2 when the beta came out and have been building projects with Hero / Burrito since August of 2010.\n
\n
If you bet bored during the presentation and want to look at some of the code samples you can check out some stuff I posted up at my web site. There are also some Android APK files there you can install and play with on your Android 2.2 device running AIR 2.6.\n
\n
There is a new project type in Flash Builder 4.5; Flex Mobile Project. This type of project should be selected when building Mobile Flex applications that will take advantage of the mobile-optimized Spark components. This session will focus on targeting AIR for Android. \nEverything I am going to talk about from this point forward assumes that you are working with Flash Builder 4.5 and Flex SDK 4.5 (v. i6 or greater) with code in a Flex Mobile Project. Certain new classes and skins are included in only the mobile libraries that are added to the class that when creating a Flex Mobile Project.\n\n
Many of the components used in mobile Flex development are the same as the Spark components you use for any app. The mobilecomponents.swc contains components and skins that have been optimized specially for mobile use-cases. You do not need to learn a whole new component set.\n
So, rendering a list of items is hard. There are all those little images and little bits of text, star icons, etc. \nNot only do you have to render all that for one item, you usually need to support anywhere between 1 item and 10,000 items. Yes, my QA team always seems to run a test with 10,000 list items ...\nNext Slide.\n
Scrolling a List of Items is Harder.\nNow, after you have the list rendered the user is going to want to scroll it. And that is where the problems start. Scrolling on a modern computer is pretty straight forward these days. Mostly we just brute-force our way through it all and don’t have too many issues. \nWhen it comes to mobile our computing resources often very restricted, AND the users get to use their fingers to swipe scroll. Instead of just ‘click to scroll up’ / ‘click to scroll down’ actions, we need to support a crazed 14 year old treating our scrollable list as practice for some new finger breakdancing fad that I, unfortunately, will never be cool enough to perform.\nBottom line, users expect immediate response to tactile gestures.\n
I cannot stress enough how important smooth and responsive scrolling is for the lists in your apps. A poorly written itemRender can ruin a whole app. If you only have time / budget to optimize one part of your application I strongly suggest spending the time writing efficient and fast itemRenderers\n
\n
If you have written components before, or read about component lifecyle, you may know that there is a whole list of ‘stuff’ that happens when RENDER kicks off. Some of that ‘stuff’ can be really expensive.\nThat is fine if I am doing it once, but if I am doing it 30 times a second for 6 items at a time I start to run into trouble. Every line of code in my ItemRenderer may be firing off over 100 times a second during a quick scroll of a long list. It is important to make every line of code count.\nNote that in the code we will be looking at today updateDisplayList() calls both drawBackground() and layoutContents() to make each easier to override without having to duplicate as much code as you would in overriding updateDispalyList() (Thanks! Adobe SDK team!)\n
It turns out a regular Spark ItemRenderer written in MXML is just not fast enough to for most mobile devices. To get around this some smart SDK devs at Adobe spent months optimizing the Spark List scrolling behavior and creating new ItemRenderers optimized specifically for mobile. The scrolling performance you may have seen in the MAX builds last fall has greatly improved. The rest of this talk will go into that.\n\n\n
While the Spark class ItemRenderer.as is still a good choice for easily creating itemRenderers for desktop and web apps there are some things about it that are not a good fit for mobile. It extends Group, and that brings along a decent amount of baggage when it comes to layout. It also encourages use of relatively expensive convenience features like states, binding, and relative layouts. In the ItemRendererSample project you can see an example of an MXML ItemRender for comparison.\n
\n
Here are the stars. Shiny new classes to learn about. During the beta process documentation really did not keep up with the code that was been written / changed each iteration. So, I just dove right in to reading the SDK code line by line to see what was going on. Building custom mobile item renderers is much easier now then it was in the early builds thanks to an attentive and responsive dev team at Adobe many of the pain points have been resolved. Hopefully I can save you some of the pain I went through today by explaining what these new super-star classes do and how / when to use them. If you get nothing else of of this session today hopefully it will be the names of these classes to read up on later.\n
Let’s look at some code. I am going to show off the code for the itemRenderer we saw a few slides back, do a quick tour, and then dive into the new classes I just mentioned. \n(show MobileShoppingCart > ItemPreviewImageRenderer.as)\n\n
Ahh, my good old friend TextField. For all the wiz-bang features that TLF text primitives have to offer TextField performs better in lists on Mobile. StyleableTextField adds a few handy features. Like \nsetting a styleDeclaration or styleName.\n
Exposes setting of the styleName property and the setStyle() method to easily change the style of the text.\n
The default itemRenderer for lists in mobile is the LabelItemRenderer. It was created specifically for rendering text in a List.\n
Here is an example of what the LabelItemRenderer looks like with default styles. \nTake a look at the way the itemRenderer is declared in MXML. This is a very convenient way to set styles and properties on your itemRenderer without impacting performance. Please note that this is different then writing an entire itemRenderer in MXML syntax. This code only instantiates the AS3 component. This is a great place to set the styles.\n
Base component that does not bring as much baggage that ItemRenderer does by extending from UIComponent.\nThere is rather limited support for styles. If it is not in the list above, the style is probably not supported. You may be able to set it in MXML or CSS, but it will do nothing at runtime.\nNothing too fancy, just renders that data property as a String. \n
Use IconItemRenderer when your item renderer has an image. Notice it extends from LabelItemRenderer\n
Here is an example of what the default IconItemRenderer might look like. Notice the image on the left is the ‘icon’ and the image on the right is the ‘decorator’.\nNotice the convenance of setting properties on the itemRenderer when instantiated in MXML syntax.\n
\n
I am not going to get too far into BitmapImage, but just be aware that it is a high performance component that performs well in mobile itemRenderers. It does not extend from DispalyObject and is a bit tricky to use. \nSide Note: using Image component, or wrapping BitmapImage in a Group is a simpler way to go, just a bit less optimal. \n
Last in, first out cache system added to Flex Framework. It is used to cache the bitmaps loaded in IconItemRenderer. If you have had to load lots of images in Flex before you probably have written a similar caching system in the past. Nothing super-fancy here. Note, however that it implements IContentLoader so that it can be used as ‘source’ value for Image components.\nYou can set the iconContentLoader to a ContentCache instance on IconItemRenderer.\n
Usage from IconItemRenderer. The imageCache object is set to the iconContentLoader so that images that get loaded are also cached. Handy!\n
\n
\n
If your itemRenderer has more then two bits of text and two images you will need to make a custom one. You have some options here. If your itemRenderer will be similar to either LabelItemRenderer or IconItemRenderer I recommend extending that class. Otherwise start with UIComponent and follow the structure of one of those default item renderers.\n
Component written in AS3 tend to perform better as item renderers when compared to components written in MXML. Use AS3. LabelItemRenderer and IconItemRenderer are highly optimized component, take advantage of what you can from those classes by extending or copying.\n
So I built a custom item renderer. I showed it in a screenshot a few slides back. I am going to detail out how I went about that.\nFirst I decided to extend IconItemRenderer since it would be easy to reuse some of the displayObjects. Next I wrote a custom component for displaying the star rating.\n
\n
\n
\n
\n
\n
set defaults in constructor\noverride createChildren()\noverride createLabelDisplay()\noverride createMessageDisplay()\nset labelFunction\nset messageFunction\nset iconFunction\noverride layoutContents()\noverride measure()\n
\n
\n
setElementSize() and setElementPosition() are helper methods that underneath the hood call the appropriate methods to change the size or position -- setLayoutBoundsSize() / setLayoutBoundsPosition() in many cases. Alway try to use these methods when resizing or positioning components.\nAlways call setElementSize() before setElementPosition()\n