I checked in some changes to List and ComboBox that allow you to create custom list items. Here’s an example:
[kml_flashembed publishmethod=“static” fversion=“10.0.0″ movie=“http://www.bit-101.com/blog/wp-content/uploads/2010/03/CustomList.swf” width=“250″ height=“200″ targetclass=“flashmovie”]
[/kml_flashembed]
This is enabled through the listItemClass property on List and ComboBox. In it, you pass in a class that must extend the ListItem class. Here’s the code for this example:
[as3]package
{
import com.bit101.components.*;
import flash.display.Sprite;
import flash.events.Event;
public class Playground extends Sprite
{
private var list:List;
private var label:Label;
public function Playground()
{
Component.initStage(stage);
label = new Label(this, 120, 10);
list = new List(this, 10, 10);
list.listItemClass = CheckListItem;
for(var i:int = 0; i < 20; i++) { list.addItem({label:“item " + i, checked:i % 2 == 0}); } list.addEventListener(Event.SELECT, onSelect); } protected function onSelect(event:Event):void { label.text = list.selectedItem.label + “. checked: " + list.selectedItem.checked; } } }[/as3] Here, I’m saying list.listItemClass = CheckListItem; We’ll see the CheckListItem class shortly. As I add items, I give each one a label property and a checked property, which is true or false. And when an item is selected, I read these properties and assign them to a label. So here’s my custom list item class: [as3]package { import com.bit101.components.CheckBox; import com.bit101.components.ListItem; import flash.display.DisplayObjectContainer; import flash.events.Event; public class CheckListItem extends ListItem { protected var _checkBox:CheckBox; public function CheckListItem(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, data:Object = null) { super(parent, xpos, ypos, data); } protected override function addChildren():void { super.addChildren(); _checkBox = new CheckBox(this, 5, 5, “”, onCheck); _label.visible = false } public override function draw():void { super.draw(); if(_data is String) { _checkBox.label = _data as String; } else if(_data.label is String) { _checkBox.label = _data.label; } else { _checkBox.label = _data.toString(); } if(_data.checked != null) { _checkBox.selected = _data.checked; } } protected function onCheck(event:Event):void { _data.checked = _checkBox.selected; } } }[/as3] In the addChildren method, I create a CheckBox and turn the existing Label invisible. In the draw method, I assign the _data.label value to the CheckBox and use _data.checked to set whether it is checked or not. As you can see, there is some additional testing for various possible label values that I basically just copied over from ListItem. When the CheckBox is clicked, it sets _data.checked to its own checked state. Since data is typed as a generic object, you can pass any property to it. For instance, if you want to display an icon or image, you might pass in an icon class or a url and use that within your list item class to instantiate or load a bitmap and display it. One thing to note is that any display objects you create in the list item may become the target of mouse click events. In checking for a list selection, the target must be the list item itself, not a child of the list item. For example, notice that when you click the CheckBox, it checks/unchecks the CheckBox, but does not select the list item. You have to click somewhere off the CheckBox to select the item. So if you have any display objects that may be capturing click events, you can set them to mouseEnabled = false, and maybe mouseChildren = false, to have them ignore clicks. The click target will then be the list item itself instead of the child. If you have children that need to be interactive, like the CheckBox in this example, make sure you leave enough space to allow for a selection-causing click as well.