How to use the Feathers List component
http://wiki.starling-framework.org/feathers/list
The List
class renders a series of items from a flat data source such as an Array
or Vector
. It includes support for selection, scrolling, custom layouts, layout virtualization, and custom item renderers.
The Basics
Let's start by creating our List
control:
var list:List = new List(); list.width = 250; list.height = 300; this.addChild( list );
Next, we want the list to display some items, so let's create a ListCollection
as its data provider. In the example below, an Array
of objects is passed to the ListCollection
.
var groceryList:ListCollection = new ListCollection( [ { text: "Milk", thumbnail: textureAtlas.getTexture( "milk" ) }, { text: "Eggs", thumbnail: textureAtlas.getTexture( "eggs" ) }, { text: "Bread", thumbnail: textureAtlas.getTexture( "bread" ) }, { text: "Chicken", thumbnail: textureAtlas.getTexture( "chicken" ) }, ]); list.dataProvider = groceryList;
ListCollection
wraps any type of data to provide a common API that the List
component can understand. Out of the box, ListCollection
automatically supports Vector
, Array
, and XMLList
, but you can create _data descriptors_ to use other types of data, if needed.
Now, we need to tell the list how to display the data. Well, actually, we need to tell the item renderer how to display the data. The default item renderer has many options for displaying text, images, and other display objects. Here, we'll tell it to use the text
property and the thumbnail
property from the items.
list.itemRendererProperties.labelField = "text"; list.itemRendererProperties.iconTextureField = "thumbnail";
When using the labelField
, the default item renderer will automatically create an appropriate text renderer to display the label. Similarly, when you use the iconTextureField
, the item renderer will automatically create and manage an Image
to display the texture. Read the documentation for the DefaultListItemRenderer
class to see all of the various fields that are available. We'll look at a couple more in more detail in a moment.
Working with the Default Item Renderer
The default item renderer of a list is a subclass of Button
, so all of the skinning and layout options available to buttons can be used by item renderers too. For example, you might want to center your content vertically and horizontally, place the icon on top, and add a gap between them:
list.itemRendererProperties.horizontalAlign = Button.HORIZONTAL_ALIGN_CENTER; list.itemRendererProperties.verticalAlign = Button.VERTICAL_ALIGN_MIDDLE; list.itemRendererProperties.iconPosition = Button.ICON_POSITION_TOP; list.itemRendererProperties.gap = 10;
Also just like buttons, the default item renderer has different touch states like down and hover. You can see how the skins for different states may be customized in the Getting Started with Feathers tutorial.
Accessories
In addition to the label and the icon, the default item renderer can display an accessory view. This is an extra display object that is often interactive in some way. For instance, you might create a list of settings with labels on the left and some user interface controls like sliders and toggle switches on the right.
An accessory may be a label, an image, or any Starling display object, including Feathers components. Similar to how you use labelField
to access text from the item, you can use accessoryLabelField
to display a second label. The default item renderer also has an accessoryTextureField
which is similar to iconTextureField
. Those two will give you the best performance when you want the accessory to display text or an image. If you need to display a UI control or any other type of display object, use the accessoryField
property.
The Components Explorer example uses accessories in the settings screens for several of the Feathers components.
Custom Item Renderers
If the default item renderer doesn't have the features that you need, the List
component offers the ability to use custom item renderers instead. Custom item renderers must implement the IListItemRenderer
interface. They should also subclass FeathersControl
.
The easiest way to pass in a custom item renderer is to set the itemRendererType
property:
list.itemRendererType = ExampleCustomItemRenderer;
Sometimes, you might want to change some properties on each item renderer as it is created. For example, if you're not using a theme, you will need to pass the skins to the item renderer when you create it. In this case, you can use the itemRendererFactory
property instead of itemRendererType
:
list.itemRendererFactory = function():IListItemRenderer { var renderer:DefaultListItemRenderer = new DefaultListItemRenderer(); renderer.defaultSkin = new Image( texture ); renderer.defaultLabelProperties.textFormat = new BitmapFontTextFormat( font ); return renderer; }
In the example above, we create the default item renderer for a List
component, but we pass in a skin and a text format.
Layout
The default layout for a list is to display the items vertically one after the other. We can change that to a horizontal layout, a tiled layout, or even a completely custom algorithm that implements the ILayout
interface. Let's switch to a HorizontalLayout
and customize it a bit:
var layout:HorizontalLayout = new HorizontalLayout(); layout.verticalAlign = HorizontalLayout.VERTICAL_ALIGN_JUSTIFY; layout.gap = 10; layout.paddingTop = layout.paddingRight = layout.paddingBottom = layout.paddingLeft = 15; list.layout = layout;
When the list automatically defaults to a VerticalLayout
, it also disables the horizontal scroll policy of its Scroller
subcomponent so that the “elastic” edges of the Scroller
only apply to the vertical direction. If we're switching to a horizontal layout, we should also adjust the scroll policies appropriately.
list.scrollerProperties.horizontalScrollPolicy = Scroller.SCROLL_POLICY_AUTO; list.scrollerProperties.verticalScrollPolicy = Scroller.SCROLL_POLICY_OFF;
Selection
The List
component may have one selected item. You can access information about selection through the selectedIndex
and selectedItem
properties. If there is no selection, the value of selectedIndex
will be -1
and the value of selectedItem
will be null
.
To listen for when the selection changes, listen to the Event.CHANGE
event:
list.addEventListener( Event.CHANGE, list_changeHandler );
The listener might look something like this:
private function list_changeHandler( event:Event ):void { var list:List = List( event.currentTarget ); trace( "selectedIndex:", list.selectedIndex ); }
To disable selection, set isSelected
to false
.
Related Links
For more tutorials, return to the Feathers Documentation.