The
Spark list-based controls are all subclasses of the SkinnableDataContainer and
ListBase classes. The SkinnableDataContainer class is designed to
display data items by using item renderers. Data items can be simple
data types, such as String and Number objects, or more complex data
types such as Object and XMLNode objects.
The ListBase class is a subclass of the SkinnableDataContainer
class. The ListBase class adds support for item selection in the
list of data items, and for controlling the text displayed in the
list. The ButtonBar, ComboBox, DropDownList, List, and TabBar controls
add additional functionality to the ListBase class.
The list-based controls are examples of data provider components.
Data provider components require data for display or user interaction.
To provide data, assign a collection which implements the IList
interface, such as an ArrayList, ArrayCollection, or XMLListCollection
object, to the control’s dataProvider property. For
more information on using data providers, see Data providers and collections.
Data items can be simple data items such as String and Number
objects, and more complicated data items such as Object and XMLNode
objects. The following example shows a List control that displays
data items represented by String data:
The executing SWF file for the previous example is shown below:
For simple data items, such as Strings and Numbers, the controls
display the entire data item as a String. For more complicated data
items, such as Objects, you can control the text displayed in the
control based on the data item. For more information, see Controlling the text displayed for each data item.
Because dataProvider is the default property
of the list-based controls, you do not have to specify a <s:dataProvider> child
tag. Therefore, you can write the example as shown below:
The executing SWF file for the previous example is shown below:
When the data items contains multiple fields, you must configure
the control to display the correct String. In the previous example,
you use the labelField property to specify to display
the firstName field in the control.
You can use several different mechanisms for controlling the
String displayed by the control:
Use the labelFunction property
The labelFunction property
lets you define a function that returns a String for display by
the control. By default, the labelFunction property takes
precedence over the labelField property.
Use the labelField property
The labelField property
specifies the field of the data item to display in the control.
Override the itemToLabel() method
Override
the itemToLabel() method to convert the data item
to a String that is then passed to an item renderer. This method
is defined on the SkinnableDataContainer class.
By default, itemToLabel() prioritizes labelFunction over labelField.
If you override itemToLabel(), you can implement
it however you like. Your implementation can then choose to use
or ignore labelField and labelFunction.
For an example that overrides this method, see Passing data using the IItemRenderer.label property.
When you use the labelFunction property, you
define a function that calculates the String to display. Typically,
the String is derived from the fields of the data item. The label
function must have the following signature:
labelFunction(item:Object):String
The item parameter contains the data
item. The function must return a String.
The following example uses a label function to concatenate the
firstName and lastName fields of each data item for display by the
control:
The executing SWF file for the previous example is shown below:
Modifying the children of a list-based control
A list-based control creates list items based on the value
of its dataProvider property. Typically, the control
creates one list item for each data item. For example, the List
control creates one list item for each data item, and the ButtonBar
control creates one button for each data item.
Use the addItem() and removeItem() methods
to manipulate the dataProvider property. A ButtonBar
control automatically adds or removes children based on changes
to the dataProvider property, as the following example
shows:
<?xml version="1.0" encoding="utf-8"?>
<!-- dpcontrols\sparkdpcontrols\SparkBBarSimpleModDP.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
// Add data item, and button, to the ButtonBar.
private function addFlexToDP():void {
myBB.dataProvider.addItem("Flex");
addFlex.enabled=false;
removeFlex.enabled=true;
}
// Remove data item, and button, from the ButtonBar.
private function removeFlexToDP():void {
myBB.dataProvider.removeItemAt(4);
addFlex.enabled=true;
removeFlex.enabled=false;
}
]]>
</fx:Script>
<s:ButtonBar id="myBB">
<mx:ArrayCollection>
<fx:String>Flash</fx:String>
<fx:String>Director</fx:String>
<fx:String>Dreamweaver</fx:String>
<fx:String>ColdFusion</fx:String>
</mx:ArrayCollection>
</s:ButtonBar>
<s:Button id="addFlex" label="Add Flex"
click="addFlexToDP();"/>
<s:Button id="removeFlex" label="Remove Flex"
enabled="false"
click="removeFlexToDP();"/>
</s:Application>
The executing SWF file for the previous example is shown below:
Setting the layout
The list-based controls support the layout property
to let you control the layout of the data items. For example, the
default layout of the List control is VerticalLayout. You can use
any of the Flex layout classes with the list-based controls, and
any custom layouts that you create.
Note: The Spark list-based controls
do not support the BasicLayout class. Do not use BasicLayout with
the Spark list-based controls.
The following example overrides that layout to use TileLayout:
The list-based classes all support the following events:
caretChange Dispatched after the focus has
changed from one data item to another. For more information, see Working with the caret item.
change Dispatched after the currently selected
data item changes to another data item. This event is dispatched
when the user interacts with the control.
When you change
the value of the selectedIndex or selectedItem properties
programmatically, the control does not dispatch the change event.
It dispatches the valueCommit event instead.
changing Dispatched before the currently
selected data item changes. This event is dispatched when the user
interacts with the control.
Calling the preventDefault() method
in the event handler prevents the selection from changing. This
event is useful when you want to perform processing on the currently
selected item before selection moves to a new data item, or to prevent
an item from being selected.
When you change the value of
the selectedIndex or selectedItem properties
programmatically, it does not dispatch the changing event.
It dispatches the valueCommit event instead.
The event object for all events is spark.events.IndexChangeEvent.
Working with the selected item
The ListBase class adds support for item selection in the
list of data items, and for controlling the text displayed in the
list. Several properties of the ListBase class handle the selection
of a data item in the control. These properties include the following:
requireSelection Specifies that a
data item must always be selected. The default is false.
If true, then the first data item is selected by
default until the user selects a list item, or until you set the selectedIndex property.
selectedIndex The index of the currently
selected data item. The index of items in the list-based controls
is zero-based, which means that values are 0, 1, 2, ... , n -
1, where n is the total number of items. If requireSelection is false,
you can also set selectedIndex to -1 to deselect
all data items.
selectedItem The object from the data provider
corresponding to the currently selected data item.
You often use these properties in event handlers, as the following
example shows for the change event. In this example,
the List control displays the firstName field of each data item.
When you select a data item in the control, the event handler for
the change event displays the index and the lastName
field of the data item in TextArea controls.
The executing SWF file for the previous example is shown below:
The currentTarget property of the object passed
to the event handler contains a reference to the List control. Therefore,
the currentTarget.selectedIndex field contains
the index of the selected item, and the currentTarget.selectedItem field
contains a copy of the selected item.
Working with the caret item
The selected item is the item in the control selected by
clicking on the item, or by using the arrow keys. For more information
about determining the selected item, see Working with the selected item.
The caret item is the data item that currently has focus. The
caret item can be the currently selected data item, or it can be
a different item.
You use the caretIndex property to determine
the index of the data item that currently has focus. The index is
zero-based, which means that values are 0, 1, 2, ... , n -
1, where n is the total number of items.
The following example displays the selectedIndex and
the caretIndex properties for a List control:
The executing SWF file for the previous example is shown below:
To see the difference between the selectedIndex and
the caretIndex properties:
Select an item in the List control by clicking on
it. Notice that because the item is both selected and in focus that
the selectedIndex and the caretIndex properties
have the same value.
Use the Up Arrow and Down Arrow keys to move the selected
item. Notice that because the item is both selected and in focus
that the selectedIndex and the caretIndex properties
have the same value.
With an item selected:
(On Windows) Hold
down the Control key, and then use the Up Arrow and Down Arrow keys
to move the caret index.
(On OSX) Hold down the Command key, and then use the Up Arrow
and Down Arrow keys to move the caret index.
Notice
that the List control displays a blue box around the data item at
the caret index, but the index of the selected item does not change.
The data item at the caret index has focus, but is not selected.
Press the Space key to select the data item at the caret index.
The list-based controls dispatch the caretChange event
when the caret item changes.
Working with item renderers
Because the list-based classes are subclasses of the SkinnableDataContainer class,
they require an item renderer to display the data items. The SkinnableDataContainer
class does not define a default item renderer. However, the list-based classes
all define a default item render as the following table shows:
A list-based control can represent any number of children.
However, each child requires an instance of an item renderer. If
the container has many children, you can notice performance degradation
as you add more children to the container.
Instead of creating an item renderer for each child, you can
use the useVirtualLayout property to configure
the control to use a virtual layout. With virtual layout enabled,
the control reuses item renderers so that it only creates item renderers
for the currently visible children of the container. As a child is
moved off the screen, possible by scrolling the container, a new
child being scrolled onto the screen can reuse its item renderer.
The layout class associated with a component determines if the
component supports virtual layout. Typically, you use the component’s
skin class to specify the layout class. By default, the skins for
the Spark list-based classes have the useVirtualLayout property
to true to enable virtual layout.
However, the default skins of some components use layouts that
do not support the useVirtualLayout property. The
TabBar and ButtonBar components use the ButtonBarHorizontalLayout
which does not support the useVirtualLayout property
or virtual layout.
Supporting view states in an item renderer for a list-based control
The Spark list-based controls support view states that
you can use in a custom item renderer. Support for these view states
is not required. If the host component attempts to set the item
renderer to a view state that is not defined in the renderer, then
the item renderer uses the normal view state.
Flex defines the following view states for item renderers.
normal The data item has no user interaction.
hovered The mouse is over the data item.
selected The data item is selected.
dragging The data item is being dragged.
normalAndShowCaret The data item is in the normal state,
and it has focus in the item list.
hoveredAndShowCaret The data item is in the hovered state,
and it has focus in the item list.
selectedAndShowCaret The data item is in the selected state,
and it has focus in the item list.
The default item renderers, including DefaultItemRenderer and
DefaultComplexItemRenderer, support all of these view states.
The list-based controls add the ability to select a data item.
Therefore, one of the view states corresponds to the data item being
selected. The item renderer can use the selected view state to modify
the appearance of the item when selected.
Several view states are associated with the caret index. The
caret index identifies the data item that has focus. That item does
not have to be the selected item,
The following example shows a simple item renderer for the List
class that supports the selected view state. In this example, the
item renderer shows the selected item in red with a black border:
This item renderer does not define all possible view states.
If the host component attempts to set it to any undefined view state,
the item renderer uses the normal state.
The following application uses this item renderer:
The executing SWF file for the previous example is shown below:
Using a mobile item renderer with a Spark list-based control
Flex provides two item renderers that you can use with
Spark list-based controls in mobile applications. These item renderers, spark.components.LabelItemRenderer and spark.components.IconItemRenderer,
are written in ActionScript to provide the highest level of performance
required by mobile applications.
The default theme for mobile applications built in Flex is the
Mobile theme. When you use the Mobile theme, Flex automatically
uses the LabelItemRenderer for the Flex list-based controls. Like
the DefaultItemRenderer, the LabelItemRenderer displays a single
text field for each data item.
You can use the IconItemRenderer in a mobile application. The
IconItemRenderer displays two text fields, one above the other,
and two icons for every data item.
The following example shows a List control defined in the view
of a mobile application. In this example, the List control uses
the IconItemRenderer to display the first name, last name, and an
icon for every data item in the list: