 |
| |
Introduction
This tutorial describes how to customize the ListBox or ComboBox UI Components
so they display a customized item symbol (such as an icon) next to label
choices. In this tutorial, you'll create the Macromedia Flash application
below. Download the sample file, customItem.fla (231
KB), to follow along with this tutorial.
This sample file requires the latest version of the Macromedia Flash Player.
Download
it now.
|
|
|
Prerequisites
To use this tutorial, you'll need to have
the Macromedia Flash
MX authoring tool installed.
Item symbol and data provider model
The ListBox and ComboBox follow a standard data/view
display model. The data (the data provider) and view (the
item symbol) are deliberately kept separate. This makes
the components more flexible and easy to modify.
It is more common to extend the item symbol
than the data provider. The data provider used is pretty
flexible, and will suffice for the most common (linear-array
based) cases. However, for the adventurous, the DataProvider
class can be found in the Library, after dragging a component
to the Stage, in Flash UI Components > Core Assets >
FUI Component Class Tree.
The FListBoxItem and FComboBoxItem
(located at Flash UI Components > Core Assets >
FUI Component Class Tree > FUI Component SubClasses >
FSelectable Item Subclasses) are both templates that help
you extend the item symbol. Both of these classes extend
FSelectableItem, which has extensive comments to
ensure easier subclassing, and where you will start writing
to create your own item symbol.
How to create a custom list item symbol
Data model
To create a custom list item, first decide on the data model
that the item will need in order to display its content.
Typically, you can use the "data" field for each item to
store additional item information. For this sample, the
code looks like the following:
list.addItem("Jim", "happy");
list.addItem("Bob", "sad");
list.addItem("Sally", "sad");
list.addItem("Doug", "happy");
list.addItem("Leslie", "happy");
list.addItem("George", "happy");
list.addItem("Debbie", "sad");
list.addItem("Sully", "happy");
list.addItem("Belle", "sad");
list.addItem("Justin", "happy");
For this sample, the included data is a simple flat structure,
but is sufficient for the example. Imagine that with a more
complex ListBox, you might use a more complex structure,
as follows:
list.addItem("Jim", { feeling:"happy",
hair:0xff0000, eyes:0x0000ff });
Note that in this case, the data field is an object that
contains information for feeling (happy/sad), hair color,
and eye color. The item symbol interprets the data field
value and displays the appropriate graphic.
Creating a custom list item movie clip and class
Use the steps below to create a custom item symbol: |
| 1 |
Duplicate the FListBoxItem
symbol in your library. |
| 2 |
Name it FCustomItem.This template
holds all the basic references you'll need to extend
from FSelectableItem. |
| 3 |
Replace FCustomItemClass with FListBoxItemClass
in the FCustomItem, as follows:
| FListBoxItem |
FCustomItem |
| #initclip 3
/*
FListItemClass
EXTENDS FSelectableItemClass
This is mostly a code stubb for extension
purposes.
*/
function FListItemClass()
{
this.init();
}
FListItemClass.prototype = new FSelectableItemClass();
Object.registerClass("FListItemSymbol", FListItemClass);
#endinitclip
|
#initclip
3
/*
FCustomItemClass
EXTENDS FSelectableItemClass
This is a customized List Item
*/
function FCustomItemClass()
{
this.init();
}
FCustomItemClass.prototype = new FSelectableItemClass();
Object.registerClass("FCustomItemSymbol",
FCustomItemClass);
#endinitclip |
|
|
In short,
you only replace FListItemClass with FCustomItemClass to
create the new custom item symbol. Note that the #initclip
number (order) does not need to be changed, and that the
new class still inherits the methods and properties of the
FSelectableItemClass. This is discussed next.
Look out for linkage IDs
Ensure that the linkage ID for your FCustomItem symbol
is correct. In the following call:
Object.registerClass("FCustomItemSymbol",
FCustomItemClass);
The class object is linked to "FCustomItemSymbol." To link
your item symbol, right-click Library. Select the "Linkage..."
dialog, and ensure the following: |
| 1 |
That the Identifier field
is set to "FCustomItemSymbol." |
| 2 |
That "Export in First Frame" is set
to ON (checked). |
|
Extending
FSelectableItemClass
At this point, it's worth taking a peek inside the FSelectableItem
symbol, which has the base code for all list and combo items.
There are three methods that mention in the comments that
they are potentially worth extending: |
| 1 |
FSelectableItemClass.prototype.layoutContent(width) |
| 2 |
FSelectableItemClass.prototype.displayContent(itmObj,
selected) |
| 3 |
FSelectableItemClass.prototype.setEnabled(enable)
Note that this last method is optional and will not
be discussed in this tutorial. |
|
Extension
#1: FCustomItemClass.prototype.layoutContent
The layoutContent(width) method controls which content
pieces are passed into the item as it's created. The original
code:
FSelectableItemClass.prototype.layoutContent
= function(width)
{
this.attachMovie("FLabelSymbol", "fLabel_mc",
2, {hostComponent:this.controller});
this.fLabel_mc._x = 2;
this.fLabel_mc._y = 0;
this.fLabel_mc.setSize(width-2);
this.fLabel_mc.labelField.selectable =
false;
}
Only adds a label to the item and sets its position and
width based on the width value passed.
For this tutorial, you will add the label to the item,
and then add a happy/sad icon to the label. Use the following
steps: |
| 1 |
Create a symbol with two
frames (happy and sad). Name it Happy-Sad Icon. |
| 2 |
Add it to the stage on a new layer
inside the item symbol. The instance name should be:
icon_mc. |
| 3 |
Override the layoutContent method
in FCustomItemClass so that you can layout
the icon_mc next to the label.
FCustomItemClass.prototype.layoutContent
= function(width)
{
this.attachMovie("FLabelSymbol",
"fLabel_mc", 2, {hostComponent:this.controller});
this.fLabel_mc._x = 2;
this.icon_mc._x = width - this.icon_mc._width
- 5;
this.fLabel_mc.setSize(width-7-this.icon_mc._width);
this.fLabel_mc.labelField.selectable
= false;
}
|
|
|
These small changes enable the icon to share space with
the label. You could extend this further to incorporate
layouts with numerous labels, icons, or components inside
the item symbol. These can either be added dynamically with
attachMovie in this method (for instance, the fLabel_mc
in this case), or in authoring time, on a layer in the Item
Symbol itself (for example, the icon_mc). In general, in
order for the items to compensate for variable sizes, this
method must be responsible for managing the size and position
of all the assets inside the item, whether dynamically placed
or done at the authoring step.
Extension #2: FCustomItemClass.prototype.displayContent
Lastly, you'll extend the displayContent method. The
original code uses a lot of logic to determine the text
that is passed to the label field. To keep this code intact,
add the following code in FCustomItemClass :
FCustomItemClass.prototype.displayContent
= function(itmObj, selected)
{
super.displayContent(itmObj, selected);
var myColor = new Color(this.icon_mc);
if (selected) {
var myColorTransform
= { ra: -100, rb: 255, ga: 172, gb: 0, ba: 100, bb: 83,
aa: 100, ab: 255};
} else {
var myColorTransform
= { ra: 100, rb: 0, ga: 100, gb: 0, ba: 100, bb: 0, aa:
100, ab: 0};
}
myColor.setTransform(myColorTransform);
this.icon_mc.gotoAndStop((itmObj.data=="happy")
? 1 : 2);
}
The displayContent method takes two simple parameters:
itmObj (an object comprised of the .label and .data fields
added during addItem) and selected (a boolean value that
indicates whether the item is selected or not). The following
explains what happens in the code snippet above. |
| 1 |
The params are sent to
the superClass' implementation of the method. This will
ensure that the label is filled with the appropriate
text. |
| 2 |
Next, it applies a color transform
to icon_mc, depending on whether the item is selected
or not. This makes the green-tinted happy face appear
when selected, and a yellow-tinted happy face appear
when it is not selected. |
| 3 |
The itmObj.data determines if this
item represents a happy or sad person. Remember, at
the beginning of this example, we used the following
:
list.addItem("Jim", "happy");
This means that .data for each object was being filled
with a "happy" or "sad" value. Depending on the contents
of .data, the icon_mc flips from either the happy
frame (1) or the sad frame (2). You can extend this
idea to use the .data field with any kind of object
or primitive data and render the item with any number
of details (such as icons, text fields, components,
and so forth) depending on the contents of the field.
|
|
Warning
Under the following conditions, the ListBox can stop
working: |
| |
If you base the
height of the item on an FLabel field. |
| |
If you are not using .label as
the property to fill the FLabel. |
|
| Luckily, it is easy
to workaround this situation. In the displayContent
method, simply add the following lines to the beginning
of the method:
if (itmObj.label
== "Sizer: PjtTopg") {
yourFLabel.setLabel(itmObj.label);
return;
}
Replace "yourFLabel" with the instance name of
the FLabel upon which the size of the item is based. |
|
Note that these are the only two methods needed to add, layout,
and display extra content in a list item.
The last step: setItemSymbol
Lastly, you'll learn how to get the ListBox to use your
item symbol choice. The call is a method of the component
named: setItemSymbol. In our sample file, the call is made
on the timeline containing the ListBox, and looks like the
following:
listBox.setItemSymbol("FCustomItemSymbol");
The ListBox uses your custom item symbol for displaying
the items. This functionality allows you to create a library
of different item symbols and dynamically swap them as different
views for the same data model.
|
|
|
About the author
Raised in the wilds of northern Canada, Nigel's keen
instincts for Macromedia Flash were honed fighting his way
through caribou herds, computing science departments, and
multimedia design firms of the pre-burst Internet economy.
A "veteran" to web design/development since 1996
(Perl!) and Macromedia Flash 3, Nigel came to Macromedia
to focus on applying his "serious" degree to his
passion for Macromedia Flash, and somehow ended up making
a whole pile of what they're calling "Macromedia Flash
UI Components." |
| |
|
|
|