Deep Dive into Flex Mobile Item Renderers


Published on

2011 360|Flex Presentation by Jason Hanson on Flex Mobile Item Renderers

Published in: Technology
  • Hi Jason:

    On slide 27, you say ContentCache acts as a LIFO queue (what would be great for caching while scrolling btw), but according to my tests (monitoring requestQueue.length and activeRequests.length):

    1. If you want to limit the number of active requests (very handy for mobile-limited bandwith scenarios), you have to enableQueueing.
    2. If you enableQueueing, it acts like a FIFO list, not LIFO.

    Can you confirm this point? Is there any other built-in way of caching+limiting the number of requests for the usual problem? (loading images for an icon renderer while scrolling lists).

    Thank you.
    Are you sure you want to  Yes  No
    Your message goes here
  • Very useful information! Please share the link to download the demo fxp.
    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
  • 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 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 >\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
  • \n
  • \n
  • \n
  • \n
  • \n
  • Deep Dive into Flex Mobile Item Renderers

    2. 2. • Jason Hanson • twitter @jayfour000 • •• Building for Flash Platform since 1999• Working with Hero SDK since Aug, 2010 (beta)
    3. 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
    4. 4. Stuff to check out if you get bored• © @atomic_playboy
    5. 5. • Special thanks to Ryan Frishberg for technical review. @frishy• All photos © Michael Schoenewies @atomic_playboy
    6. 6. New Project Type in Flash Builder 4.5• Flex Mobile Project
    7. 7. Rendering a Listof Items is Hard
    8. 8. Scrolling a Listof Items is Harder
    9. 9. 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
    10. 10. Rendering Items is Expensive• Look! new data. • commitProperties()• How big am I? • measure()• Update display • updateDisplayList()• > Draw background • > drawBackground()• > Layout • > layoutContents()
    11. 11. 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
    12. 12. What About the MXML• 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
    13. 13. New Classes on Next Slide (Don’t Panic)
    14. 14. New Classes• spark.components.supportClasses •• spark.components • • >• spark.primitives • (updated in 4.5)• spark.core •
    15. 15. Sample ItemRenderer (show code)
    16. 16.• Lightweight text control that supports Styles
    17. 17. • 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()
    18. 18.• Optimized default ItemRenderer
    19. 19. • 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
    20. 20. IconItemRenderer• Image and text
    21. 21. • 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’
    22. 22. BitmapImage• Lightweight image component
    23. 23. ContentCache• LIFO Cache Object
    24. 24. • .maxCacheEntries• .maxActiveRequests
    25. 25. What If I’m Special?
    26. 26. Roll Your Own• Options • Extend UIComponent • Extend LabelItemRenderer • Extend IconItemRenderer
    27. 27. • 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
    28. 28. iconDisplay
    29. 29. labelDisplayiconDisplay
    30. 30. labelDisplay iconDisplaymessageDisplay
    31. 31. labelDisplay iconDisplay decoratorDisplaymessageDisplay
    32. 32. Custom Component starRating
    33. 33. ItemPreviewImageRenderer (Show Code) • set defaults in constructor • override createChildren() • override createLabelDisplay() • override createMessageDisplay() • set labelFunction • set messageFunction • set iconFunction • override layoutContents() • override measure()
    34. 34. 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
    35. 35. 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
    36. 36. END
    37. 37. Intentional Left Blank
    38. 38. • Extra Slides After This Point
    39. 39. A Note onDisplayObjectSharingMode • Can reuse a displayobject in multiple location (TODO: fill this out)
    40. 40. MultiDPIBitmapSource• Optional source object for images