Flash AS3 Tutorial: How To Put TileList Pictures Beside Label Text

Leave a comment Standard

So I wanted to make a chat room list with icons formatted beside it and I thought, why not just use a TileList? It already shows images and scrolls so I’ll save myself some trouble. I thought it would incredibly easy and intuitive to change the layout of how the images/label were being displayed but BOY WAS I WRONG!! So hoping to save you the three days of research I spent trying to figure this out here you go:

1. Create a new as3 flash .fla file. Modify the properties and click on the settings next to where it says Actionscript 3. Uncheck the strict errors and warnings boxes.

2. Click on the components tab in the library and drag the TileList component onto the stage. Do the same for a Label component.

3. Delete the TileList and Label components from the stage. You’ll notice they are still available in your library.

4. Create a new as3 file called myTileList.as and put it in the same location as the as3 .fla file.

5. Find the properties section for the .fla file. Where it says class type in myTileList. This will tell the .fla we want to load this .as file when we compile and then execute our flash file.

6. Create three new movie clip objects called Mod_Icon, Reg_Icon and Speaker_Icon. These are the images that will show up beside the user names in the list. Now take a .png image and put it in an icons folder in the same location as your .fla and .as files. We’ll use this so you can see the difference in how to load external files and how to load display objects. Save your myTileList.fla file.

6. Now we’ll update the myTileList file so that it adds a TileList to the stage so we can do some simple interactions with it. Put this into your myTileList file:

* File: myTileList.as
* Author: design1online.com, LLC
* Date: 9.4.2011
* Purpose: display a list of chat room user
package {

    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;

    import fl.controls.Label;
    import fl.events.ListEvent;
    import fl.controls.TileList;
    import fl.controls.ScrollPolicy;
    import fl.controls.ScrollBarDirection;
    import fl.data.DataProvider;

    import UserListRenderer;

    public class myTileList extends MovieClip {

        private var msg_lbl:Label = new Label();

        private var user_tilelist:TileList = new TileList();

        * Purpose: default constructor
        * Precondition: none
        * Postcondition: build what appears on the stage
        public function myTileList()

            //add the TileList to the stage
            user_tilelist.width = 170;
            user_tilelist.height = 100;
            user_tilelist.move(200, 40);
            user_tilelist.columnWidth = 170;
            user_tilelist.rowHeight = 30;
            user_tilelist.visible = true;
            user_tilelist.direction = ScrollBarDirection.VERTICAL;

            * this tells the tileList to use our userListRenderer class to
            * change the way it displays each item in the list
            user_tilelist.setStyle("cellRenderer", UserListRenderer);

            //this adds the list to the stage

            //add a label to the stage to show what we've selected
            msg_lbl.width = 170;
            msg_lbl.height = 100;
            msg_lbl.x = 200;
            msg_lbl.y = 150;
            msg_lbl.text = "Select a user above.";
            msg_lbl.visible = true;

            //Add an event listener
            user_tilelist.addEventListener(ListEvent.ITEM_CLICK, clickUserHandler);

            //Load the list


        * Purpose: draw the users list
        * Precondition: none
        * Postcondition: user list has been updated
        private function loadUserList()

            var dp_mod:DataProvider = new DataProvider();
            var dp_reg:DataProvider = new DataProvider();
            var dp_speak:DataProvider = new DataProvider();
            var dp_users:DataProvider = new DataProvider();
            var users:Array = [{name:"John", privileges:"mod"}, {name:"Amy", privileges:"regular"}, {name:"Lucas", privileges:"reg"}, {name:"Claire", privileges:"speaker"}];  
            var icon = Reg_Icon;

            for (var u:String in users)
                switch (users[u].privileges)
                    case "mod":
                        icon = Mod_Icon; //is a moderator using the movie clips we have in the library
                        dp_mod.addItem( {label: users[u].name, source: icon, data:users[u] });
                    case "regular":
                        icon = Reg_Icon; //is a regular member
                        dp_reg.addItem( {label: users[u].name, source: icon, data:users[u] });
                    case "reg":
                        icon = "icons/reg.png"; //you can also use a URL or a relative link to where this image is uploaded
                        dp_reg.addItem( {label: users[u].name, source: icon, data:users[u] });
                    case "speaker":
                        icon = Speaker_Icon; //is a speaker
                        dp_speak.addItem( {label: users[u].name, source: icon, data:users[u] });

            //sort the lists
            dp_reg.sortOn("label", [Array.DESCENDING, Array.NUMERIC, Array.CASEINSENSITIVE]);
            dp_mod.sortOn("label", [Array.DESCENDING, Array.NUMERIC, Array.CASEINSENSITIVE]);
            dp_speak.sortOn("label", [Array.DESCENDING, Array.NUMERIC, Array.CASEINSENSITIVE]);

            //merge the lists

            //our final list is sorted by type and user name
            user_tilelist.dataProvider = dp_users;

        private function clickUserHandler(evt:Event)
            * We have to use evt.rowIndex to get the selected user from the
            * TileList because the event fires before the TileList selectedIndex
            * has been updated. If you're trying to get an item from the tileList
            * and you're not inside one of it's event handlers you would use
            * user_tilelist.selectedIndex in place of evt.rowIndex
            var selectedUser:Object = user_tilelist.getItemAt(evt.rowIndex).data;

            msg_lbl.text = selectedUser.name + " is a " + selectedUser.privileges;

7. Create another as3 .as file and call it UserListRenderer. We’ll use this to change how our TileList looks so the pictures appear beside the label. Put this into your UserListRendererfile:

* File: UserListRenderer.as
* Author: design1online.com, LLC
* Date: 9.4.2011
* Purpose: change the formatting for the user tile list
*    so images appear beside the user name
package {

    import fl.controls.listClasses.ICellRenderer;
    import fl.controls.listClasses.ImageCell;
    import fl.controls.TileList;
    import flash.text.*;

    public class UserListRenderer extends ImageCell implements ICellRenderer {

        public var desc:TextField = new TextField();
        private var textStyle:TextFormat = new TextFormat();

        public function UserListRenderer() {

            //inherit the variables from the parent

            //we don't want to stretch our images to fit the size of the box
            loader.scaleContent = false;

            //change the cursor as if this was a button
            useHandCursor = true;

            //Create and format the text field
            //that will appear beside the image
            desc.autoSize = TextFieldAutoSize.LEFT;
            desc.x = 24;
            desc.y = 5;
            desc.width = 150;
            desc.height = 28;
            desc.multiline = false;
            desc.wordWrap = false;

            //apply some styles to our text field
            setStyle("imagePadding", 2);
            textStyle.font = "Tahoma";
            textStyle.color = 0x000000;
            textStyle.size = 15;

        * Now we override the function that draws the layout
        * so we can move the image beside the text
        override protected function drawLayout():void {

            //adjust the icon for any existing padding
            var imagePadding:Number = getStyleValue("imagePadding") as Number;

            //offset the image in the box so it's not touching the top of it
            loader.move(0, 4);

            var w:Number = width-(imagePadding*2);
            var h:Number = height-(imagePadding*2);

            if (loader.width != w && loader.height != h) {

            //re-draw the image

            //hide the original cellImage textField so we can display our new one later
            textField.visible = false;

            //display the new text box beside our image
            desc.text = data.label;

            //adjust the background
            background.width = width;
            background.height = height;


8. That’s it! You can load images from the stage directly into the tile list or you can load images from an external URL. I’ve created a .zip you can download that shows you how to do it along with figuring out which item is selected, changing labels and images, and sorting the list.

Download the Working Code


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s