Learn how to create a simple virtual layout in Flex 4
2010-10-26 22:50
459 查看
March 6th, 2010 Leave a comment Go to comments
This post goes over the basics of writing a very simple custom layout that supports virtualization in spark. It assumes that you have already built a custom layout that handles the real (non-virtual) case and are comfortable doing so.
The main difference between a virtual and non-virtual layout is how many renderers are created. A non-virtual layout creates a renderer for every item at startup, where virtual layouts only create renderers for items that are currently in view. This is a huge performance gain when you have dataProviders with thousands of items, but only a handful are shown at any given time. The spark List turns on virtual layout by default.
The layout we build here is called SimpleHorizontalLayout. As the name suggests, it is a very simplistic approach to something like the spark HorizontalLayout. It extends LayoutBase and lays out elements next to each other from left to right. It assumes that every element is the same size as the typicalLayoutElement (which is the renderer created for the typicalItem). If the typicalItem is not specified by the user then the first item in the dataProvider will be used by default.
Here is a rough outline of what to do when writing a virtual layout:
start with a layout that works in the real (non-virtual) case
override measure()
override updateDisplayList()
override scrollPositionChanged()
If you want your layout to support keyboard navigation in a spark List then you will also need to:
override getElementBoundsLeftOfScrollRect() etc.
override getElementBounds()
override getNavigationDestinationIndex()
1. Override measure()
In virtual layouts, the measure method should only rely on size data cached at updateDisplayList() time. Everything else (that’s everything the first time measure is called) has to be estimated. In this simple case we guess at the size by assuming that every renderer is the same size as the typicalLayoutElement.
2. Override updateDisplayList()
In the non-virtual case you are able to loop through every element in the target and lay them all out. This means that the target’s contentWidth/contentHeight is calculated exactly. But in the virtual case you don’t have this luxury, you know a couple of things: the scroll position, the size of the target, and the typicalLayoutElement. Given these things you will need to figure out which indices are actually in view and layout only those elements. I like to follow this procedure when tackling this step:
1. Figure out what we’re given
2. Given the scroll position figure out the first index that should be in view
3. Figure out how many indices are in view
4. Figure out the last index in view
5. Figure out what coordinates to position the first index at
6. Position the renderer of each index that is in view using getVirtualElementAt()
7. Keep track of how many pixels visible renderers are hanging off the ends of the view
The important thing about a virtual layout updateDisplayList() method is that it can only retrieve elements with target.getVirtualElementAt() and that it should only retrieve the elements it needs. Also getVirtualElementAt() should never be called outside of the updateDisplayList() in the layout. Currently only DataGroup supports virtual layouts. It does so by allocating the renderers requested by layout.updateDisplayList(), freeing the rest.
3. Override scrollPositionChanged()
When the scroll position changes it might mean that new items are coming into view so we need to invalidate the display list if that is the case. You’ll notice that this sample has an optimization that only invalidates the display list if the scroll position has changed enough to expose new renderers. This is done by taking advantage of the Flash scrollRect and knowing that the renderers that are only partially in view can be valuable in saving extra invalidations.
4. Override getElementBoundsLeftOfScrollRect() etc.
This method returns the bounds of the first layout element that either spans or is to the left of the scrollRect’s left edge. This gets called when someone clicks on the track or the arrows of the List’s scrollbar.
5. Override getElementBounds()
This method returns a Rectangle that corresponds to the layout bounds of the item at the given index. A virtual layout overrides this method to compute a potentially approximate value for elements that are not in view. This works together with getNavigationDestinationIndex() to support keyboard navigation.
6. Override getNavigationDestinationIndex()
This method returns the index that the List should scroll to given a specific keyboard navigation command like HOME, END, LEFT, RIGHT, etc.
Example
You can find the code equivalent to this procedure in the source of SimpleHorizontalLayout.as in the following example: http://flexponential.com/2010/03/06/learn-how-to-create-a-simple-virtual-layout-in-flex-4/
This post goes over the basics of writing a very simple custom layout that supports virtualization in spark. It assumes that you have already built a custom layout that handles the real (non-virtual) case and are comfortable doing so.
The main difference between a virtual and non-virtual layout is how many renderers are created. A non-virtual layout creates a renderer for every item at startup, where virtual layouts only create renderers for items that are currently in view. This is a huge performance gain when you have dataProviders with thousands of items, but only a handful are shown at any given time. The spark List turns on virtual layout by default.
The layout we build here is called SimpleHorizontalLayout. As the name suggests, it is a very simplistic approach to something like the spark HorizontalLayout. It extends LayoutBase and lays out elements next to each other from left to right. It assumes that every element is the same size as the typicalLayoutElement (which is the renderer created for the typicalItem). If the typicalItem is not specified by the user then the first item in the dataProvider will be used by default.
Here is a rough outline of what to do when writing a virtual layout:
start with a layout that works in the real (non-virtual) case
override measure()
override updateDisplayList()
override scrollPositionChanged()
If you want your layout to support keyboard navigation in a spark List then you will also need to:
override getElementBoundsLeftOfScrollRect() etc.
override getElementBounds()
override getNavigationDestinationIndex()
1. Override measure()
In virtual layouts, the measure method should only rely on size data cached at updateDisplayList() time. Everything else (that’s everything the first time measure is called) has to be estimated. In this simple case we guess at the size by assuming that every renderer is the same size as the typicalLayoutElement.
2. Override updateDisplayList()
In the non-virtual case you are able to loop through every element in the target and lay them all out. This means that the target’s contentWidth/contentHeight is calculated exactly. But in the virtual case you don’t have this luxury, you know a couple of things: the scroll position, the size of the target, and the typicalLayoutElement. Given these things you will need to figure out which indices are actually in view and layout only those elements. I like to follow this procedure when tackling this step:
1. Figure out what we’re given
2. Given the scroll position figure out the first index that should be in view
3. Figure out how many indices are in view
4. Figure out the last index in view
5. Figure out what coordinates to position the first index at
6. Position the renderer of each index that is in view using getVirtualElementAt()
7. Keep track of how many pixels visible renderers are hanging off the ends of the view
The important thing about a virtual layout updateDisplayList() method is that it can only retrieve elements with target.getVirtualElementAt() and that it should only retrieve the elements it needs. Also getVirtualElementAt() should never be called outside of the updateDisplayList() in the layout. Currently only DataGroup supports virtual layouts. It does so by allocating the renderers requested by layout.updateDisplayList(), freeing the rest.
3. Override scrollPositionChanged()
When the scroll position changes it might mean that new items are coming into view so we need to invalidate the display list if that is the case. You’ll notice that this sample has an optimization that only invalidates the display list if the scroll position has changed enough to expose new renderers. This is done by taking advantage of the Flash scrollRect and knowing that the renderers that are only partially in view can be valuable in saving extra invalidations.
4. Override getElementBoundsLeftOfScrollRect() etc.
This method returns the bounds of the first layout element that either spans or is to the left of the scrollRect’s left edge. This gets called when someone clicks on the track or the arrows of the List’s scrollbar.
5. Override getElementBounds()
This method returns a Rectangle that corresponds to the layout bounds of the item at the given index. A virtual layout overrides this method to compute a potentially approximate value for elements that are not in view. This works together with getNavigationDestinationIndex() to support keyboard navigation.
6. Override getNavigationDestinationIndex()
This method returns the index that the List should scroll to given a specific keyboard navigation command like HOME, END, LEFT, RIGHT, etc.
Example
You can find the code equivalent to this procedure in the source of SimpleHorizontalLayout.as in the following example: http://flexponential.com/2010/03/06/learn-how-to-create-a-simple-virtual-layout-in-flex-4/
相关文章推荐
- Learn How To Create Trigger In Oracle Forms
- UDK: Lightmap UV Layout Techniques & How to Create a Second UV Channel in Maya
- How to Create a Virtual Drive in Windows XP
- How to create simple and advanced pivot tables in C# and ASP.NET
- ★ Learn how you can use Adobe Creative Suite to create skins for Flex and AIR applications.
- How to create aligned partitions in Linux for use with NetApp LUNs, VMDKs, VHDs and other virtual di
- how to create virtual network in OS X 10.9
- How to create simple web service in VS2010, NOT WCF service
- How to re-create STM File in Exchange 2000/2003
- How to create new module in npm
- How to Run Mac OS X in VirtualBox on Windows
- How to create custom ViewEngine in MVC 2
- How to create a Toastmasters speech in 30 minutes
- How to create a read-only user in TFS source control
- how to add Javascript and CSS in page layout with sharepoint 2013
- How to Create Mysite in SharePoint 2010
- How To Create a Child Domain in Active Directory and Delegate the DNS Namespace to the Child Domain
- How to Modify the Virtual Memory in a Mac
- How to use virtual path providers to dynamically load and compile content from virtual paths in
- How to use the new CSS syntax in Flex 4