MadComponents0_6_0.swc is available now.
MadComponents is a free open-source library to make user interfaces for Flash/AIR on Mobile. (iPhone, Android, etc.). MadComponents projects can be authored using either Flash, Flex (Flash Builder), or command line tools (amxmlc, adt).
The main update to this version is a new list component called <longList>. The older list components are rendered on creation. So a long list would be created when the application starts up – which could impact on app start-up performance. But the <longList> component is rendered lazily, when list rows come into view. There is also a recycle option:
<longList recycle=”true”/>
Enabling recycle re-uses list rows that have rolled off the screen, rather than instantiating new list rows. So it is optimised to minimise run time memory.
(Note that <longList> only employs this lazy row rendering or recycling for custom row layouts).
MadComponents is now open-source. You can access the source from here. While MadComponents has always been free to use, I wanted to wait until the library was mature and stable before releasing the source.
I’ve also published the asdoc documentation at http://e2easy.byethost9.com/madcomponents .
In related news, Michael Martinez is writing a series of blog articles on MadComponents here.
A MadComponents Logo
Can anyone anyone make a MadComponents logo? (for free obviously). It would be nice to have a logo.
Help Spread the Word
I’ve contributed MadComponents freely to the Flash Mobile developer community. Please help spread the word about MadComponents and ExtendedMadness, by blogging and twittering. It would be great if you could contribute more examples and tutorials, or even just talk about these libraries and what they can do.
I’ve had feedback from a few developers wanting a way to combine MadComponents with Flash Builder 4.5 for mobile. I intended MadComponents as a lighweight alternative to using the Flex framework. So while I don’t really like the idea of mixing them – it’s certainly possible to incorporate MadComponents within an MXML layout. All it takes is a few custom component wrappers.
Note: I’ve now put the code for these wrappers into the SVN code repository.


For example, here’s a UIForm wrapper extending SpriteVisualElement:-
package custom {
import com.danielfreeman.madcomponents.Attributes;
import com.danielfreeman.madcomponents.UIForm;
import flash.display.Sprite;
import spark.core.SpriteVisualElement;
public class FlexUIForm extends SpriteVisualElement
{
protected var _component:Sprite;
protected var _gap:Number = 0;
protected var _xml:XML;
protected var _attributes:Attributes;
public function FlexUIForm() {
}
override public function setLayoutBoundsSize(width:Number, height:Number, postLayoutTransform:Boolean=true):void {
if ( isNaN( width ) )
width = getPreferredBoundsWidth( postLayoutTransform );
if ( isNaN( height ) )
height = getPreferredBoundsHeight( postLayoutTransform );
if (!_component) {
createComponent(width - 2*_gap, height - 2*_gap);
}
else {
resizeComponent(width - 2*_gap, height - 2*_gap);
}
super.setLayoutBoundsSize(width, height, postLayoutTransform);
}
protected function createComponent(width:Number, height:Number):void {
_attributes = new Attributes(0, 0, width, height);
_attributes.parse(_xml);
_component = new UIForm(this, _xml, _attributes);
_component.x = _gap;
_component.y = _gap;
}
protected function resizeComponent(width:Number, height:Number):void {
_attributes.width = width;
_attributes.height = height;
UIForm(_component).layout(_attributes);
}
public function get component():Sprite {
return _component;
}
public function set xml(value:XML):void {
_xml = value;
}
override public function get height():Number {
return _component ? _component.height + _gap : super.height;
}
override public function get width():Number {
return _component ? _component.width + _gap : super.width;
}
}
}
The code above is pretty standard, except overriding width, and height. This compensates for components that incorporate masking.
Notice, we can specify a MadComponents layout, and pass it to the xml property.
We can use our FlexUIForm component as a base class for specific components. I anticipate that Flex developers are going to really like my picker component, so let’s specify a wrapper for that:-
package custom {
import com.danielfreeman.madcomponents.Attributes;
import com.danielfreeman.madcomponents.UIForm;
public class FlexUIPicker extends FlexUIForm {
protected var _columns:int = 1;
protected var _data:Array = null;
protected var _xmlData:XML = null;
protected var _widths:String = "";
protected var _pickerHeight:String = "";
public function FlexUIPicker() {
_gap = 10;
}
public function set columns(value:int):void {
_columns = value;
}
public function set widths(value:String):void {
_widths = value;
}
public function set pickerHeight(value:String):void {
_pickerHeight = value;
}
public function set data(value:Array):void {
if (_component) {
var pickerIndex:int = 0;
for each (var columnData :Array in value) {
UIForm(_component).pages[pickerIndex++] = columnData;
}
}
else {
_data = value;
_xmlData = null;
}
}
public function set xmlData(value:XML):void {
if (_component) {
var pickerIndex:int = 0;
for each (var columnData :XMLList in value) {
UIForm(_component).pages[pickerIndex++] = columnData[0];
}
}
else {
_xmlData = value;
_data = null;
}
}
override protected function createComponent(width:Number, height:Number):void {
var xml:String = '<columns gapH="0" width="'+width.toString()+'"';
if (_pickerHeight!="") {
xml += ' pickerHeight="' + _pickerHeight.toString() + '"';
}
if (_widths!="") {
xml += ' widths="' + _widths + '"';
}
xml += '>';
var index:int = 0;
for(var i:int = 0; i<_columns; i++) {
xml += '<picker>' + theData(index++) + '</picker>';
}
_xml = XML(xml + '</columns>');
super.createComponent(width, height);
}
protected function theData(value:int):String {
if (_data) {
var result:String = '<data>';
for each (var item:String in _data[value]) {
result+='<item label="'+item+'"/>';
}
return result+'</data>';
}
else if (_xmlData) {
var group:String = _xmlData.group[value].toString();
return "<data"+group.substring(group.indexOf(">"),group.lastIndexOf("<"))+"</data>";
}
else {
return "";
}
}
}
}
Notice within createComponent, we build up a string for the picker bank xml, that incorporates the xml data for each picker. We can specify this data either as a two dimensional array (assigned to data), or as a grouped data XML (assigned to xmlData).
While I’ve allowed the user to specify columns, pickerHeight, and widths within the MXML component, I haven’t gone as far as allowing every MadComponent property to be defined. I wanted to demonstrate the principle of how to make a MadComponents wrapper, so I leave it as an exercise for the reader to expand and refine what I’ve shown here. So, I’ve omitted the ability to specify colour, colours, index (for each picker) and the font for the labels in each picker row.
It would be great if someone wants to expand on what I’ve done and write a complete set of Flex wrappers for MadComponents, and share them with the community. I don’t have the time or inclination to pursue this myself. It would be great to see spin-offs from MadComponents, in the same way that minimal comps has spawned spin-off projects. (MadComponents will be open-source soon – when I feel it is mature, stable, developed, and robust enough to release – but for now the .swc library is free to use, or extend.).
The final two wrappers are for UISlider and UISwitch.
package custom {
import com.danielfreeman.madcomponents.UISlider;
public class FlexUISlider extends FlexUIForm {
public function FlexUISlider() {
}
override protected function createComponent(width:Number, height:Number):void {
_component = new UISlider(this, 0, 0, new <uint>[]);
UISlider(_component).fixwidth = width;
}
override protected function resizeComponent(width:Number, height:Number):void {
UISlider(_component).fixwidth = width;
}
}
}
package custom {
import com.danielfreeman.madcomponents.UISwitch;
public class FlexUISwitch extends FlexUIForm {
public function FlexUISwitch() {
}
override protected function createComponent(width:Number, height:Number):void {
_component = new UISwitch(this, 0, 0);
}
override protected function resizeComponent(width:Number, height:Number):void {
}
}
}
Finally, the root MXML project that demonstrates all four of these wrappers in action:-
<?xml version="1.0" encoding="utf-8"?>
<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" minWidth="955" minHeight="600"
xmlns:mad="custom.*">
<fx:Script>
<![CDATA[
protected static const LAYOUT:XML =
<horizontal>
<slider id="slider2" value="0.2" width="130" background="#CCCC00,#999933,#AAAA99"/>
<button id="slideDown" colour="#CC9933" alt="true">button</button>
</horizontal>;
protected static const GROUPED_DATA:XML =
<data>
<group>
<Black/>
<Red/>
<Orange/>
<Yellow/>
<White/>
<Green/>
<Blue/>
<Indigo/>
</group>
<group>
<January/>
<February/>
<March/>
<April/>
<May/>
<June/>
</group>
<group>
<item label="1"/>
<item label="2"/>
<item label="3"/>
<item label="4"/>
<item label="5"/>
</group>
</data>;
]]>
</fx:Script>
<s:VGroup width="300" height="400">
<mad:FlexUISlider percentWidth="100"/>
<mad:FlexUISwitch/>
<mad:FlexUIForm xml="{LAYOUT}" percentWidth="100"/>
<mad:FlexUIPicker columns="3" xmlData="{GROUPED_DATA}" widths="50%,50%,40" percentWidth="100" height="200" />
</s:VGroup>
</s:Application>
Help Spread the Word
I’ve contributed these components freely to the Flash Mobile developer community. Please help spread the word about MadComponents and ExtendedMadness, by blogging and twittering. It would be great if you could contribute more examples and tutorials, or even just talk about these libraries and what they can do.
Please click on the star on the Project Home page (log-in to see it under Project Information), to show your appreciation of MadComponents.
I wanted to keep MadComponents lightweight. So I packed the most essential UI components and data capabilities into a small library. But I had more UI components that I wanted to contribute to Adobe mobile developers. So I created ExtendedMadness. The ExtendedMadness .swc does everything that the MadComponents .swc does, but also includes more components and charts. The treeNavigation, and DataGrid, which were deprecated in MadComponents, have also made their way into ExtendedMadness.
Just like MadComponents, you can use ExtendedMadness within Flash or Flex (Flash Builder). You can utilise it in Mobile AIR applications, or desktop AIR applications, or browser web services. You use the same XML layout language as MadComponents, and you can freely mix MadComponents, and ExtendedMadness tags.
(If you don’t know about MadComponents yet – I recommend that you read other posts on this blog, and gain some insight into the approach, before reading any further).

Above you can see combo-boxes (drop-down menu), Cut-copy-paste control, segmented controls, checkboxes, and radio buttons. Below are four examples of charts included in ExtendedMadness.
Set up an ExtendedMadness project
If you have a project utilising MadComponents (and you can read detailed tutorials on this blog about how to do that), then you can change it to an ExtendedMadness project as follows:-
1. Replace the MadComponents.swc library with an ExtendedMadness.swc library.
2. Ensure you have these imports at the top of the program:-
import com.danielfreeman.extendedMadness.*; import com.danielfreeman.madcomponents.*;
3. Put another line of code above the UI.layout() statement:-
UIe.activate(this); // Gives us access to extended components UI.create(this, LAYOUT);
(Note UIe - the “e” is not a typing error).
4. Now you can use extended tags in the XML layout.
Now let’s go through the components shown above, and how to describe them in XML.
Combo-box Menu.

<menu value=”choose…”> {DATA} </menu>
Where DATA is defined in the usual way:-
<data> <dog/> <cat/> <goldfish/> </data>
You can define a width, and alternative appearance for a menu. You can also define a font:-
<menu value=”choose…” width=”100″ alt=”true”> <font size=”20″/> {DATA} </menu>
Usually, alt=”true” means that the component style will be smaller, and more appropriate for desktop or browser use, rather than mobile use.
Listen for a menu selection like this:-
var menu:UIMenu = UIMenu(UI.findViewById(“menu”)); menu.addEventListener(UIMenu.SELECTED, menuSelected);
protected function menuSelected(event:MyEvent):void { // import asfiles.MyEvent trace(“menu: “+event.parameters[0]+” “+event.parameters[1]); }
Segmented Control

<segmentedControl> {DATA} </segmentedControl>
You can also specify width, alignH, alt=”true”, or background colours to customise appearance. Listen for button clicks like this:-
protected var _segmentedControl:UISegmentedControl;
_segmentedControl = UISegmentedControl(UI.findViewById(“segmentedControl”)); _segmentedControl.addEventListener(Event.CHANGE, segmentedControlChanged);
protected function segmentedControlChanged(event:Event):void { trace(“segmented control: “+_segmentedControl.index); }
checkBox

<checkBox/>
<checkBox alt=”true”/>
protected var _checkBox:UICheckBox;
_checkBox = UICheckBox(UI.findViewById(“checkBox”)); _checkBox.addEventListener(Event.CHANGE, checkBoxChanged);
protected function checkBoxChanged(event:Event):void { trace(“check box:”+_checkBox.state); }
radioButton

<columns widths=”50,50,50″> <radioButton/> <radioButton/> <radioButton/> </columns>
_radioButtons = UIPanel(UI.findViewById(“radioButtons”)); _radioButtons.addEventListener(UIRadioButton.TOGGLE, radioButtonsChanged);
protected function radioButtonsChanged(event:MyEvent):void { trace(“radio button: “+UIRadioButton(event.parameters[0]).name); }
Charts
ExtendedMadness includes five kinds of chart. pieChart, barChart, lineChart, scatterChart, and horizontalChart (horizontal barChart). Some charts are automatically calibrated, according to how much space the graph takes in the layout. When the user clicks on a chart, a tool-tip appears.
By default, pieChart, barChart, and horizontalChart are rendered in 3D. Change them to 2D as follows:-
<pieChart render=”2d”/>
barChart and horizontalChart can be stacked as follows:-
<barChart stack=”true”/>
Assign data to the chart within the XML layout, or in ActionScript. For example,
protected static const MATRIX:XML = <data> <row>1,2,3,4</row> <row>3,8,4,1</row> <row>4,1,5,12</row> <row>7,14,0,4</row> <row>6,8,3,1</row> <row>5,7,9,2</row> </data>;
<barChart>{MATRIX}</barChart>
or in ActionScript:-
var barChart:UIBarChart = UIBarChart(UI.findViewById(“barChart”)); barChart.data = [[4,3,2,5,6],[4,8,15,16,23]]; // or barChart.xmlData = <data><row>4,3,2,5,6</row><row>4,8,15,16,23</row></data>;
The charts interpret the data row-by-row, unless you specify column-by-column like this:-
<barChart id=”barChart” order=”column”/>
Customise Chart Colours
There are a few ways to change the colours of a chart. You can use a different colour palette. There are four preset palettes. ”rainbow”, “subtle”, “greyscale0″ and “greyscale1″. Some palettes look best with order=”row” (default), and some look best with order=”column”. So it’s worth experimenting. For example:-
<barChart stack=”true” palette=”subtle” order=”columns”>{MATRIX}</barChart>
A palette is a cyclic-list of preset colours. To start at a specific place in that list, use paletteStart, like this:-
<horizontalChart id=”hChart” paletteStart=”5″/>
Another way to specify chart colours is to use a custom colour list, like this:-
protected static const COLOURS:XML = <colours>#99FF99,#CC9999,#9999CC,#CCCC66,#CC9966</colours>;
<pieChart>{COLOURS}{DATA}</pieChart>
SVG Renderer
I’ve been completely self-indulgent, and included an SVG renderer in the library. You can specify vector images between the <svg> tags. I made this SVG parser myself, and it’s pretty good, with a few quirks occasionally, where the result differs from what you get in a browser. Of course, on a mobile screen, it’s better to use .jpg bitmap images rather than to render complex vector images.
I got this particular SVG sample from http://www.openclipart.org.
Get ExtendedMadness
Flash users can download the ExtendedMadness.swc from http://code.google.com/p/mad-components/downloads/list .
Flex (Flash Builder) users can check-out the latest .swc and MadComponents demos from the Subversion repository at: http://code.google.com/p/mad-components/source/checkout .
Example code using ExtendedMadness can be found here.
Help Spread the Word
I’ve contributed these components freely to the Flash Mobile developer community. Please help spread the word about MadComponents and ExtendedMadness, by blogging and twittering. It would be great if you could contribute more examples and tutorials, or even just talk about these libraries and what they can do.
In this final MadComponents tutorial we’re going to look at the third and final Flash Builder 4.5 tutorial (from here), and do it the MadComponents way. Adobe’s Flex Test Drive for Mobile: Build a mobile application in an hour, takes you through building an AMF web service, and then building a mobile client application that connects to that service. We’re going to build the same application using MadComponents.
AMF is a binary format used to serialise ActionScript objects. A binary AMF packet is usually significantly smaller than REST XML or SOAP packet. Hence AMF services are typically much faster.
This tutorial assumes that you have some expertise in building web services, using PHP, Coldfusion, or Java. But if you’d rather do a tutorial where the web service already exists, then have a go at building a twitter client.
We recommend that you first take a look at the first six parts of this tutorial series, which will bring you up-to-speed with using MadComponents.
Here is what our application will look like, one the right, next to the original Flash Builder 4.5 version:-

So let’s get started, and go though the steps to build our MadComponents Mobile application:-
Set Up The Web Service
1. You’ll need to set up an AMF web service. You can do this using PHP, Coldfusion, or Java. You can download the resources from here. Follow the instructions in the original Flash Builder tutorial. Just follow the section entitled “Setup for PHP”, “Setup for ColdFusion”, or “Setup for Java”, depending which server-side technology you want to use. Don’t go further than the section entitled “Step 2: Create a Flex Mobile project. We’re going to do everything else the MadComponents way. If having looked at the Flex tutorial, you want a peek at how much easier it is using MadComponents, look here.
Creating the project
Create a new MadComponents project. We’ve already learnt how to do this in previous tutorials, but I’ll copy the steps here to save you looking it up.
2. If you haven’t done so, download MadComponents. Familiarise yourself with the demos, and see what it can do.
Flash users can download the project from http://code.google.com/p/mad-components/downloads/list .
Flex (Flash Builder) users can check-out the latest .swc and MadComponents demos from the Subversion repository at: http://code.google.com/p/mad-components/source/checkout .
Please click “like” on the Google code site, if you like MadComponents.
Although the pictures below depict MadComponentsLib0_5.swc, you’ll need the latest version. Currently MadComponentsLib0_5_7.swc (or a newer version when available).
3A. If you’re using Flash. You need to find your libs folder. For Flash CS5, you’ll find this directory at the following path, from your Flash application folder:-
Adobe_Flash_CS5/Common/Configuration/ActionScript_3.0/libs
Once you’ve found this folder, put MadComponentsLib into it:-

3B. If you’re using Flash Builder (Flex), just include the .swc into the project in the usual way.
( Project -> Properties -> ActionScript Build Path -> Library Path -> Add SWC Folder… lib )


4. Create a new ActionScript application. Call it “MadTwitterTrends”. Either Adobe AIR ActionScript applications, or a browser based application.
5. For an Adobe AIR application, set your window size to 300 x 454. (not applicable to a browser application). In Flash, you’ll see this in the properties panel:-
( On a real device, it will adapt to the screen size, but in simulation – it assumes 300 x 454 pixels )
6. Now save your application. In Flash, make sure you’ve made a new folder for it.
7. In Flex, you’ll already have a top ActionScript class. In Flash you’ll need to create one. File->New->ActionScript File. Call it “MadTestDrive.as”. Save it in the same folder as MadTestDrive.fla .
8. In Flash, create a link between the timeline project, and the ActionScript file. (No need to do anything in Flex). Click on the first cell on the timeline, and in the Actions Panel, type:
new MadTestDrive(this);
Now we’re ready to write some code.
Model for AMF Service
We’re going to connect to our AMF service. The EmployeeService.getEmployeesSummary method returns an array of objects. Here is an example of an object:-
{id:7, firstname:”Elizabeth”, lastname:”Roe”, title:”Senior Experience Designer”, photofile:”eroe.jpg”}
We’re going to represented each of these objects by a row in a list, using a custom item renderer like this:-


We use a model tag to map the object properties, onto the item renderer:-
<model url=”http://localhost/MobileTestDrive/gateway.php” service=”EmployeeService.getEmployeesSummary” action=”loadAMF”> <firstname>label</firstname> <lastname>label</lastname> <photofile>image</photofile> <title/> <id/> </model>
title, and id are mapped onto components of the same name. (Actually, there is no component named id, but the row data will contain this property). photofile is mapped onto image. Note that both firstname and lastname are mapped onto the same label. MadComponents will concatenate the two strings, so that “Elizabeth” and “Roe” becomes “Elizabeth Roe”.
Here is our first program with the list, model, and custom renderer:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
public class MadComponentsAMF0 extends Sprite {
protected static const AMF_LIST:XML = <list id="list" sortBy="lastname">
<model url="http://localhost/MobileTestDrive/gateway.php" service="EmployeeService.getEmployeesSummary" action="loadAMF">
<firstname>label</firstname>
<lastname>label</lastname>
<photofile>image</photofile>
<title/>
<id/>
</model>
<horizontal>
<imageLoader alignV="centre" id="image" base="http://localhost/TestDrive/photos/">40</imageLoader>
<vertical>
<label id="label"/>
<label id="title"><font size="10" color="#999999"/></label>
</vertical>
</horizontal>
</list>;
public function MadComponentsAMF0(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, AMF_LIST);
}
}
}

Notice how we’ve ordered the list by lastname. sortBy=”lastname”
Searching
We can easily add a search field to this list. Within the <list> tags, put:-
<search field=”label”/>
With field=”label”, we don’t need to write any code. When the user types text into the search field, it filters the list rows by the label field.
Detail Page
When the user clicks on a list row, we want to display a detail page with more details, such as cell phone number, office phone number, email, and office.

<columns id=”detail” widths=”80,100%”> <imageLoader id=”photofile” base=”http://localhost/TestDrive/photos/”>80</imageLoader> <vertical gapV=”0″> <label><b>Title</b></label> <label id=”title”>{FONT}</label> <label/> <label><b>Cell Phone</b></label> <label id=”cellphone”>{FONT}</label> <label/> <label><b>Office Phone</b></label> <label id=”officephone”>{FONT}</label> <label/> <label><b>Email</b></label> <label id=”email”>{FONT}</label> <label/> <label><b>Office</b></label> <label id=”office”>{FONT}</label> <label/> </vertical> </columns>
This time, we’ve utilised ids that correspond to the property names in the EmployeeService.getEmployeesByID service. (photofile, title, cellphone, officephone, email, office). So we don’t have to specify any mappings within the <model> tags. We can just write:-
<model url=”http://localhost/MobileTestDrive/gateway.php” service=”EmployeeService.getEmployeesByID”/>
Notice there’s no action attribute. We’re going to control it using actionscript.
Putting it together
We’re going to put the list and the detail page into a <navigation> container.
<navigation id=”navigator” autoTitle=”label”> {AMF_LIST} {DETAIL} </navigation>
autoTitle=”label” tells the navigation container to automatically take a property called label from the list item clicked, and set the navigation container’s title to this string.
We are going to load the detail page under actionscript control. When the user clicks on a list row, we want to extract the id for that row, and pass it as a parameter to the EmployeeService.getEmployeesByID service.
protected function pageChange(event:Event):void { if (_navigator.pageNumber == 1) { _detail.data = {image:null}; //clear old image in detail page _detail.model.loadAMF(“”, “”, [_navigator.row.id]); } else { _navigator.title = “”; } }
The heart of this code sample is the line:-
_detail.model.loadAMF(“”, “”, [_navigator.row.id]);
The first parameter is the URL, the second parameter is the service. But as we’ve already specified both of these in the model tag, so we just pass an empty string “”, to utilise our defaults. The third parameter is an array of parameters. _navigator.row.id is the id of the list row clicked.
Putting all the pieces together, here is the complete code:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
public class MadComponentsAMF extends Sprite {
protected static const AMF_LIST:XML = <list id="list" sortBy="lastname">
<model url="http://localhost/MobileTestDrive/gateway.php" service="EmployeeService.getEmployeesSummary" action="loadAMF">
<firstname>label</firstname>
<lastname>label</lastname>
<photofile>image</photofile>
<title/>
<id/>
</model>
<search field="label"/>
<horizontal>
<imageLoader alignV="centre" id="image" base="http://localhost/TestDrive/photos/">40</imageLoader>
<vertical>
<label id="label"/>
<label id="title"><font size="10" color="#999999"/></label>
</vertical>
</horizontal>
</list>;
protected static const FONT:XML = <font size="14"/>;
protected static const DETAIL:XML = <columns id="detail" widths="80,100%">
<model url="http://localhost/MobileTestDrive/gateway.php" service="EmployeeService.getEmployeesByID"/>
<imageLoader id="photofile" base="http://localhost/TestDrive/photos/">80</imageLoader>
<vertical gapV="0">
<label><b>Title</b></label>
<label id="title">{FONT}</label>
<label/>
<label><b>Cell Phone</b></label>
<label id="cellphone">{FONT}</label>
<label/>
<label><b>Office Phone</b></label>
<label id="officephone">{FONT}</label>
<label/>
<label><b>Email</b></label>
<label id="email">{FONT}</label>
<label/>
<label><b>Office</b></label>
<label id="office">{FONT}</label>
<label/>
</vertical>
</columns>;
protected static const NAVIGATION:XML = <navigation id="navigator" autoTitle="label">
{AMF_LIST}
{DETAIL}
</navigation>;
protected var _detail:UIForm;
protected var _navigator:UINavigation;
public function MadComponentsAMF(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, NAVIGATION);
_detail = UIForm(UI.findViewById("detail"));
_navigator = UINavigation(UI.findViewById("navigator"));
_navigator.addEventListener(Event.CHANGE, pageChange);
}
protected function pageChange(event:Event):void {
if (_navigator.pageNumber == 1) {
_detail.data = {image:null};
_detail.model.loadAMF("","",[_navigator.row.id]);
}
else {
_navigator.title = "";
}
}
}
}
What’s next ?
That was the last in this series of tutorials. I set out to show how the could be utilised to create powerful and lightweight mobile applications – but also how MadComponents can simplify the development process – making them a viable alternative to Flash Builder. I’m bound to be blogging more about MadComponents, so watch this space, and keep the feedback and questions coming.
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation or examples for Flash at http://code.google.com/p/mad-components/downloads/list
There are also lots of code examples to view or check-out from the subversion repository at http://code.google.com/p/mad-components/source/checkout
Please subscribe to this blog if you want to catch subsequent posts about MadComponents.
Extended Madness
You may have noticed ExtendedMadness on the download site. I’ll be blogging about it soon. ExtendedMadness library is an alternative to MadComponents. It does everything that MadComponents does, but has lots more components. (Take a look at the MadComponentsDesktop.as example on the code repository.) I wanted to keep the core MadComponents library light, and that’s why further components have been included in the bigger ExtendedMadness library.
Please Blog about MadComponents
Please help spread the word about MadComponents and blog or twitter about it. It would be great if you could contribute more examples and tutorials, or even just talk about MadComponents, and what it can do.
So far, we’ve mostly concentrated on list-based mobile applications. A lot of applications rely on lists and list-based navigation. But in this tutorial, we’re going to explore more features of MadComponents. Tab-based applications, View Flippers, Groups, Scrolling Containers, Pop-Ups and Sliding drawers.
To get the most out of this tutorial, we recommend that you read the previous parts, 1 to 5.
Upgrade to the Latest Version
Over the last few weeks, there have been a lot of improvements to MadComponents. At the time of writing, version0.5.6 is the latest. So we recommend that you download MadComponentsLib0_5_6.swc, or a later version when available.
Flash users can download the project from http://code.google.com/p/mad-components/downloads/list .
Flex (Flash Builder) users can check-out the latest .swc and MadComponents demos from the Subversion repository at: http://code.google.com/p/mad-components/source/checkout .
Please click “like” on the Google code site, if you like MadComponents.
Note that <treeNavigation> is deprecated. And the <dataGrid> was deprecated and removed. But both these classes will make a come-back in a forthcoming new extended MadComponents library.
Tab-Based Applications
You can use <tabPages> to navigate between pages using tab buttons.
<tabPages id=”pages”> {PAGE1} {PAGE2} {PAGE3} <tabPages>
This layout will result in three tab buttons at the bottom of the screen. They are automatically numbered 0,1,2… If you want to assign a label, and/or icon to each button, you accomplish this in ActionScript:-
var tabPages:UITabPages = UITabPages(UI.findViewById(“tabPages”));Where ICON0, ICON1, and ICON2 are image classes that you’ve embedded, like this:-
tabPages.setTab(0, “categories”, ICON0);
tabPages.setTab(1, “add”, ICON1);
tabPages.setTab(2, “search”, ICON2);
[Embed(source="images/list.png")] protected static const ICON0:Class;
Typically the icons are 20×20 pixels.
A variation on the tab bar style is achieved by including the alt=”true” attribute. I’ve also specified a dark colour here:-
<tabPages id=”pages” alt=”true” colour=”#111122″>

View Flippers
A view flipper allows the user to change page using a swiping gesture, pulling the pages left and right with a finger movement.
<viewFlipper> {PAGE1} {PAGE2} {PAGE3} </viewFlipper>
To change the colour of the ‘dots’, at the bottom of a view flipper page, or to change the colour of the scroll bar, for any container that has one – use the scrollBarColour attribute. For example:-
<viewFlipper scrollBarColour=”#FFFFFF”>
A view flipper can be utilised as a scrolling gallery, where the scrolling region is smaller than a page. There’s an example of this in the code repository. You can see it here.

Groups
You’ll notice that the pages shown above depict grouped items. Like this:-

Here, we have two input fields, inside a group:-
<group> <input prompt=”First” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> <input prompt=”Last” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/>
</group>
( Notice, we’ve set the background to white, so that it’s invisible against the white background )
Let’s add another rows to the group. A field for a phone number:-
<group> <input prompt=”First” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> <input prompt=”Last” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> <input prompt=”Number” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> </group>
Let’s put a label before the Number field:-
<group> <input prompt=”First” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> <input prompt=”Last” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> <horizontal> <label>phone:</label> <input prompt=”Number” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> </horizontal> </group>
Finally, we can put a dividing line between the word “phone:”, and the input field. We modify the layout by including a lines=”true” setting:-
<horizontal lines=”true”> <label>phone:</label> <input prompt=”Number” alignH=”fill” background=”#FFFFFF,#FFFFFF,#FFFFFF”/> </horizontal>
clickableGroup
A clickable group is similar to a group in the grouped list that we learnt about in tutorial 3. The difference between a clickable group, and a grouped list, is that every row of a grouped list uses the same item renderer. But with a clickable group, every row may have a different layout.

Here is the layout we used:-
protected static const GROOOP:XML =<clickableGroup id="group" gapV="30" stageColour="#E9E9EF,#EFEFEF,8">
<horizontal>
<image>{getQualifiedClassName(DOG_ICON)}</image>
<label>Daniel Freeman</label>
</horizontal>
<horizontal>
<label alignV="centre">http://madskool.wordpress.com</label>
<arrow alignV="centre" alignH="right"/>
</horizontal>
<horizontal>
<label alignV="centre">http://e2easy.wordpress.com</label>
<arrow alignV="centre" alignH="right"/>
</horizontal>
</clickableGroup>;
Listen for Event.CHANGE to detect row clicks. The index property will return the index of the row clicked. Here’s a complete example:-
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.utils.getQualifiedClassName;
import flash.events.Event;
import com.danielfreeman.madcomponents.*;
public class MadGroups extends Sprite
{
[Embed(source="images/dogicon.png")]
protected static const DOG_ICON:Class;
protected static const GROOOP:XML =<clickableGroup id="clickableGroup" gapV="30" stageColour="#E9E9EF,#EFEFEF,8" background="#EEEEFF,#FFFFFF,#FFFFFF">
<horizontal>
<image>{getQualifiedClassName(DOG_ICON)}</image>
<label>Daniel Freeman</label>
</horizontal>
<horizontal>
<label alignV="centre">http://madskool.wordpress.com</label>
<arrow alignV="centre" alignH="right"/>
</horizontal>
<horizontal>
<label alignV="centre">http://e2easy.wordpress.com</label>
<arrow alignV="centre" alignH="right"/>
</horizontal>
</clickableGroup>;
protected var _clickableGroup:UIForm;
public function MadGroups(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, GROOOP);
_clickableGroup = UIForm(UI.findViewById("clickableGroup"));
_clickableGroup.disableClickableGroupRows([0]);
_clickableGroup.addEventListener(UIForm.CLICKED, clickHandler);
}
protected function clickHandler(event:Event):void {
trace("row clicked="+_clickableGroup.index);
}
}
}
Notice how we’ve disabled the first row:-
_clickableGroup.disableClickableGroupRows([0]);
And we’ve set this first row to a different colour to the others:-
background=”#EEEEFF,#FFFFFF,#FFFFFF”
The result looks like this:-

Scrolling Containers
To make a page scrollable, place it inside a <scrollVertical> container:-
<scrollVertical> {PAGE} </scrollVertical>To control the scroll position from ActionScript, you can assign to the scrollPositionY property:-
var scroller:UIScrollVertical = UIScrollVertical(UI.findViewById(“list”)); scroller.scrollPositionY = 100.0;
The scrollXY container is often utilised to contain an image, or a page, allowing a user to pan around, scrolling in both directions. You must specify a width and a height as follows:-
<scrollXY width=”640″ height=”480″ border=”false”> <image> {getQualifiedClassName(BIG_PICTURE)} </image> </scrollXY>;
A common convention is that the user double taps on the screen to enlarge a view. We can achieve this, without any coding, simply by including a tapToScale=”3.0″ setting.
<scrollXY width=”640″ height=”480″ border=”false” tapToScale=”3.0″>
In this case “3.0″ is the magnification that will be used, when the picture is double-clicked.
You can find a code example demonstrating this (and other examples) on the MadComponents code repository.
Pop-Ups
Create a modal pop-up window using the UI.createPopUp() method, like this:-
_popUp = UI.createPopUp(POPUP_LAYOUT, 180.0, 200.0);
Where 180 is the width, and 200 is the height of the window.
To hide, and show a pop-up, use:-
UI.hidePopUp(_popUp);
and
UI.showPopUp(_popUp);
respectively.
If you no longer require a pop-up, you can remove it permanently, using:-
UI.removePopUp(_popUp);
Activity Indicator
An activity indicator is a rotating symbol that symbolises something is processing, or waiting.

To show and hide an activity indicator use:-
UI.showActivityIndicator();
and
UI.hideActivityIndicator();
Sliding Drawer
In the first tutorial, we used the goToPage() method to navigate between pages. We utilised two transitions. UIPages.SLIDE_LEFT and UIPage.SLIDE_RIGHT. There are also transitions for pages that slide up and down over the currently viewed page. For example:-
<pages id=”pages”> {PAGEo} {PAGE1} </pages> var pages:UIPages = UIPages(UI.findViewById(“pages”)); pages.goToPage(1, UIPages.SLIDE_UP); . . . pages.goToPage(1, UIPages.SLIDE_DOWN);
The <pages> container is like <tabPages>, but without tabs. You control page changes in ActionScript. It is the base class of <tabPages>, <navigation>. So the above example will still work substituting <pages> for <tabPages> or <navigation>.
Note that the page number parameter to remove a page with a SLIDE_DOWN transition must be the same as the parameter we used to change to slide the page in. In this example, 1.
A variation on pages that slide up or down are sliding drawers. With a sliding drawer, you still see a portion of the original page, under the sliding drawer (But you can’t click on it, even though you can see it.). The drawer height is always the same, regardless of screen size, device resolution, or orientation:-

What’s next ?
In the next tutorial we’re going to look at the third and final Flash Builder 4.5 tutorial (from here), and do it the MadComponents way. While most developers are attracted to MadComponents’ UI components, its data capabilities for XML, JSON and AMF are possibly underrated. Adobe’s Flex Test Drive for Mobile tutorial shows how a mobile client app can connect to an Adobe AMF web service. The next tutorial will show how this can be accomplished much more simply with MadComponents. And how the MadComponents application is much smaller than the application generated with Flash Builder 4.5.
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation or examples for Flash at http://code.google.com/p/mad-components/downloads/list
There are also lots of code examples to view or check-out from the subversion repository at http://code.google.com/p/mad-components/source/checkout
Please subscribe to this blog if you want to catch subsequent tutorials.
Please Blog about MadComponents
Please help spread the word about MadComponents and blog about it. It would be great if you could contribute more examples and tutorials, or even just talk about MadComponents, and what it can do.
So far, we’ve built some Mobile applications using MadComponents and Pure ActionScript. Now we’re going to learn how to deploy them to mobile devices (Android, iPhone, iPad, etc..). If you’re using a new version of Flash CS5.5, or Flash Builder 4.5, then you’ll already know how to do this from the application. But If you haven’t yet rushed out and bought the latest upgrade, then read on… because you can use Adobe’s FREE Flex SDK tools.
One Core, Many Flavours
MadComponents is IDE agnostic, so you might have built your application using Flash, or Flash Builder (Flex), or a third-pary free IDE such as AXDT or Flash Develop. Because MadComponents is based on standard ActionScript, with no AIR-only features, you might even test the core of your mobile application in the browser.
This is what I do. I divide my AIR Mobile projects into two parts, separating the AIR and non-AIR code. First I develop a core ActionScript project. No exotic AIR classes. It runs in the browser, or anywhere, and you don’t need Adobe’s latest development tools to develop it.
Now I can extend this core, or derive several variants from it if I wish. One for iPhone, One for Android, One for desktop AIR, One for the browser, etc.
So now if want to add AIR mobile classes, to handle accelerometer events, or utilise the sqlite database, or whatever – I put this AIR code in a separate class. It extends the top class of my core project, and makes it specific to mobile deployment. You can use free command-line tools to build this project if your IDE doesn’t support AIR.
Anyway, this is the way I structure my AIR projects. It may, or may not suit you.
Adobe’s free Flex SDK
You can get the latest release version of Adobe’s free Flex SDK from http://www.adobe.com/cfusion/entitlement/index.cfm?e=flexsdk
(There are downloads for MacOS and Windows. I’m not sure what the situation is for Linux now. Anyone? – can you leave a comment if you know).
Once you download this folder, you may or may not want to move it somewhere convenient in your filesystem. On my Mac, I’d move it to the Developer directory.
Optionally, set a path to the “bin” folder.
amxmlc
amxmlc is the compiler for air applications. Let’s assume your top application class is called MadProject.as, inside a MadProject folder.
1. Start up your terminal / command-line window.
2. Set the directory to your MadProject project folder. For example,
cd /Users/danielfreeman/Desktop/MadProject
3. Compile the project. This creates a familiar .swf file. Let’s assume that you also want to include the MadComponentsLib, you would write:-
/Developer/flex_sdk_4/bin/amxmlc -library-path+=MadComponentsLib0_5_5.swc MadProject.as
i. I’m assuming that the path to amxmlc is /Developer/flex_sdk_4/bin/. But if you’ve put the Flex SDK somewhere else, change the path appropriately. If you’ve set up a path, you can omit the path.
ii. I’m assuming that you’re using MadComponentsLib0_5_5.swc. But if you’re using a later version, change this filename.
iii. I’ve assumed that there’s a copy of the .swc library inside the MadProject folder. Alternatively, set a path to where it is.
When you type this command into the terminal window, it should create your MadProject.swf file.


Android application.xml
We’re going to use adt to create a .apk file for android. But first, we’re going to make an application.xml file:-
<?xml version="1.0" encoding="utf-8" standalone="no"?> <application xmlns="http://ns.adobe.com/air/application/2.7"> <id>MadTest</id> <filename>MadTest</filename> <name>MadTest</name> <versionNumber>0.1</versionNumber> <description>MadTest example</description> <supportedProfiles>mobileDevice</supportedProfiles> <initialWindow> <content>MadTest.swf</content> <visible>true</visible> <fullScreen>true</fullScreen> <aspectRatio>portrait</aspectRatio> <autoOrients>true</autoOrients> </initialWindow> </application>
This is a very simple template that you can apply to your own projects. For more information about further options, refer to the documentation at http://help.adobe.com/en_US/air/build/WS5b3ccc516d4fbf351e63e3d118666ade46-7ff1.html Or you can take a look at samples/descriptor-sample.xml in the Flex SDK you downloaded.
The options for <aspectRatio> are portrait or landscape. This determines the initial orientation of your application when it is run. If you set the <autoOrients> parameter to false, then it will stay in this orientation, and it won’t adjust to device orientation.
Android Permissions
For Android applications, you need to specify permissions for various resources that you use in your application. So if your app uses the internet, or geolocation, or some other privileged resource – you need to give yourself permission. You need to specify these permissions inside the application.xml file. You would put the following XML before the </application> tag above.
<android>
<manifestAdditions>
<![CDATA[
<manifest>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
]]>
</manifestAdditions>
</android>
(More information about permissions here.)
Signing your application
All Android applications must be signed. We can use Adobe’s adt tool to create a signing certificate:-
/Developer/flex_sdk_4/bin/adt -certificate -cn -validityPeriod 25 myidentifier 1024-RSA myCertificate.pfx mypassword
Where mycertificate and mypassword are strings of your own choosing. This will create a .pfx certificate file called myCertificate.pfx. If you want to put your application on an Android market, you must create a certificate that’s valid for at least 25 years, Hence -validityPeriod 25.
Creating the Android app
Now we’ve prepared the three ingredients to make our android .apk app. The compiled .swf file, the application.xml and the self-signed certificate. We can use adt to package for Android:-
/Developer/flex_sdk_4/bin/adt -package -target apk -storetype pkcs12 -keystore myCertificate.pfx -storepass mypassword MadProject.apk application.xml MadProject.swf
This command will create the Android .apk file.
Installing on an Android phone
We can use Google’s adb tool to install the .apk file on an Android phone. (Get it here.) On a Windows PC, you may need a driver to allow your PC to talk to your phone. There’s an install folder in the SDK, that may be relevant to your system. On a Mac, it just works. So if you have a driver, plug your phone into your computer.
First of all, you’ll need to install the AIR runtime for Android. You’ll find it in the Flex SDK. (runtimes/air/andoid/device/Runtime.apk)
adb -r install Runtime.apk
You only need to install the runtime once. Not every time. Now install your application.
adb -r install MadProject.apk
Building an iPhone application
Now, we’re going to package the same application for iPhone. Last, time we didn’t make any app icons, so let’s go through that step this time. And we’ll need an application.xml file for iPhone.
Making Icons
Use an image editor to make an icon, and export four .png files of different sizes. 29×29 pixels, 57×57 pixels, 72×72 pixels and 512×512 pixels. For test purposes, you can just create blank .pngs. Put these four images into an icons folder inside your MadProject folder.
iPhone application.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?> <application xmlns="http://ns.adobe.com/air/application/2.7"> <id>MadProject</id> <filename>MadProject</filename> <name>MadProject</name> <versionNumber>0.1.0</versionNumber> <supportedProfiles>mobileDevice</supportedProfiles> <initialWindow> <renderMode>gpu</renderMode> <content>hello.swf</content> <visible>true</visible> <fullScreen>true</fullScreen> <aspectRatio>portrait</aspectRatio> <autoOrients>true</autoOrients> </initialWindow> <supportedProfiles>mobileDevice</supportedProfiles> <icon> <image29x29>icons/icon29.png</image29x29> <image57x57>icons/icon57.png</image57x57> <image72x72>icons/icon72.png</image72x72> <image512x512>icons/icon512.png</image512x512> </icon> <iPhone> <InfoAdditions> <![CDATA[ <key>UIStatusBarStyle</key> <string>UIStatusBarStyleBlackOpaque</string> <key>UIRequiresPersistentWiFi</key> <string>NO</string> ]]> </InfoAdditions> </iPhone> </application>
<renderMode> gpu means that we’re going to use hardware accelerated graphics. Notice how we’ve referenced our four icon files.
Provisioning Profile and Developer Certificate
To export to iPhone, iPad, or Ipod, you need to be a paid-up Apple Developer. Within the members area of http://developer.apple.com, you can create and download a provisioning profile, and a developer certificate.
Packaging for iPhone
So we have the following ingredients that we will use to make a .ipa file for iPhone.
1. A compiled .swf file. MadProject.swf
2. An iPhone application.xml file. applicationiPhone.xml
3. Application Icons. icon29-icon512.png
4. An Apple developer certificate. developerKey.p12
5. An Apple provisioning profile. docProfile.mobileprovision
Use adt to build the .ipa as follows. (Prior to Flex 4.5 SDK, we used to use a tool called “pfi” (packager for iPhone), but this is now deprecated).
/Developer/flex_sdk_4/bin/adt -package -target ipa-debug -provisioning-profile docProfile.mobileprovision -storetype pkcs12 -keystore developerKey.p12 -storepass mypassword MadProject.ipa applicationiPhone.xml MadProject.swf icons/icon29.png icons/icon57.png icons/icon72.png icons/icon512.png
Ok, that’s a long command to type in. I usually paste all of these commands into a .txt file that I keep in my project folder. So every time I want to use it, I copy and paste to pop it into my terminal window.
You can install this .ipa application on your iPhone, iPod, or iPad using iTunes. For more information about adt, take a look here.
What’s next ?
In the next tutorial we’re going to delve deeper into MadComponent’s capabilities. Advanced Navigation, Scrolling containers, Tab-based applications, View Flippers, Groups, Pop-Ups, and Sliding Drawers.
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation at http://code.google.com/p/mad-components/downloads/list
There are also lots of code examples to view or check-out from the subversion repository at http://code.google.com/p/mad-components/source/checkout
Please subscribe to this blog if you want to catch subsequent tutorials.
At the start of this tutorial series, I made comparisons between using MadComponents, and using Flash Builder 4.5 mobile components. Certainly, the MadComponents project is much more lightweight. I believe it is also easier to develop. In this tutorial, you’ll have the opportunity to compare for yourself. We are going build the same application from a Flex Builder 4.5 tutorial, created by Narciso Jaramillo at Adobe. Build your first mobile Flex application – Twitter Trends. But we’re going to do it the MadComponents way.
UPDATE 4 September ’11: There was a small change in the twitter API, so I’ve updated the code to reflect this.
UPDATE 20 November’11: I’ve changed the code to compensate for further Twitter API changes. The updated version is here. Please ensure you’re using the latest version of MadComponents. This tutorial will be updated at a later date.

MadComponents is IDE agnostic. So you can follow this tutorial using Flash, Flex, or some third-party IDE. For development, you don’t need the latest version of the Flash Player, or AIR – and you can even develop and test your app in the browser if you like.
I’ll assume that you’ve got the latest version of the MadComponents library from my download page. Or Flex users can check-out latest demos from the subversion repository. If you’d like a sneak peek to the end result of this tutorial – it’s called MadComponentsJSON.as. You can take a look here. (Yup – that’s it. Surprisingly simple with MadComponents, isn’t it.).
If you haven’t read the first three tutorials, I’d recommend that you do that – so you know what’s what.
Creating the project
So let’s go through the steps to build this app. We create the project in the same way that we did for our hello world tutorial 1 project. (In fact, I’ve copied and pasted the instructions below).
1. If you don’t have the latest version of MadComponents, you can download it from http://code.google.com/p/mad-components/downloads/list
Although the pictures below depict MadComponentsLib0_5.swc, you’ll need the latest version. Currently MadComponentsLib0_5_3.swc (or a newer version when available).
2A. If you’re using Flash. You need to find your libs folder. For Flash CS5, you’ll find this directory at the following path, from your Flash application folder:-
Adobe_Flash_CS5/Common/Configuration/ActionScript_3.0/libs
Once you’ve found this folder, put MadComponentsLib into it:-

2B. If you’re using Flash Builder (Flex), just include the .swc into the project in the usual way.
( Project -> Properties -> ActionScript Build Path -> Library Path -> Add SWC Folder… lib )


3. Create a new ActionScript application. Call it “MadTwitterTrends”. Either Adobe AIR ActionScript applications, or a browser based application.
4. For an Adobe AIR application, set your window size to 300 x 454. (not applicable to a browser application). In Flash, you’ll see this in the properties panel:-
( On a real device, it will adapt to the screen size, but in simulation – it assumes 300 x 454 pixels )
5. Now save your application. In Flash, make sure you’ve made a new folder for it.
6. In Flex, you’ll already have a top ActionScript class. In Flash you’ll need to create one. File->New->ActionScript File. Call it “MadTwitterTrends.as”. Save it in the same folder as MadTwitterTrends.fla .
7. In Flash, create a link between the timeline project, and the ActionScript file. (No need to do anything in Flex). Click on the first cell on the timeline, and in the Actions Panel, type:
new MadTwitterTrends(this);
Now we’re ready to write some code.
The Model Tag
In the previous tutorial, we learnt about lists. So we’re going to start with a list. We can populate a list from an online server feed, and express this in our layout using the <model> tag as follows:-
<list id=”trendsView”> <model url=”http://api.twitter.com/1/trends/available.json” action=”loadJSON”> <name>label</name> <url/> </model> </list>
We can see that the url specified the address of the JSON web service. If we paste this address into the browser, we can see what the data looks like:-
[ {"name":"#listentoyourheart","url":"http:\/\/search.twitter.com\/search?q=%23listentoyourheart"}, {"name":"#youneedtositdown","url":"http:\/\/search.twitter.com\/search?q=%23youneedtositdown"}, etc...etc...
Within this data, is an array of records, called "trends". And we can see that each object contains a "name" and a "url". Let's look again at our layout:-
<list id="trendsView"> <model url="http://api.twitter.com/1/trends/available.json" action="loadJSON"> <name>label</name> <url/> </model> </list>
Each object inside this array will become one row of our list. The "name" field of the object will be mapped onto the label of the row. The "url" field will also be stored inside each row (but in this case it won't be displayed).
8. With your MadTwitterTrends.as file, write the following program:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
public class MadTwitterTrends extends Sprite {
protected static const TRENDS_VIEW:XML =
<list id="trendsView">
<model url="http://api.twitter.com/1/trends/available.json" action="loadJSON">
<name>label</name>
<url/>
</model>
</list>;
public function MadTwitterTrends(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, TRENDS_VIEW);
}
}
}
9. Run the program, and you’ll see a list of twitter trends.
A Custom Renderer
When we click on any twitter trend row, we want another list to be displayed. A specific twitter feed. The layout for this second list is as follows:-
<list autoLayout=”true” id=”tweetsView”> <model path=”results”/> <horizontal> <imageLoader id=”profile_image_url”/> <vertical gapV=”0″> <label id=”from_user” alignH=”fill”></label> <label id=”text” alignH=”fill”>{SMALL_TEXT}</label> </vertical> </horizontal> </list>
If you read the previous tutorial, you’ll probably recognise this as a list with a custom renderer. Each row, consists of an image, and two text labels. Like this:-
The ids of each MadComponent (profile_image_id, from_user, text) actually correspond to the names of the fields inside the JSON array of records at path=”results”. This is why we didn’t need to write anything between the <model> and </model> tags.
10. Let’s test out this list layout. Modify your MadTwitterTrends.as file, so that it looks like this:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
public class MadTwitterTrends extends Sprite {
protected static const SMALL_TEXT:XML = <font size="12"/>;
protected static const TWITTER_VIEW:XML =
<list autoLayout="true" id="tweetsView">
<model url="http://search.twitter.com/search.json?q=%23listentoyourheart" path="results" action="loadJSON"/>
<horizontal>
<imageLoader id="profile_image_url"/>
<vertical gapV="0">
<label id="from_user" alignH="fill"></label>
<label id="text" alignH="fill">{SMALL_TEXT}</label>
</vertical>
</horizontal>
</list>;
public function MadTwitterTrends(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, TWITTER_VIEW);
}
}
}

Just for test purposes, we specified a url and an action:-
<model url=”http://search.twitter.com/search.json?q=%23listentoyourheart” path=”results” action=”loadJSON”/>
But when we write our application, we’re going to control this using ActionScript.
Load data under ActionScript control
In the example above, we’re always loading the same twitter page. Notice the parameter after the ? in the url. search.json?q=%23listentoyourheart. We want this parameter to come from the twitter trends row that’s clicked. We’re going to extract it from the “url” field of the twitter trends data.
{“name”:”#youneedtositdown”,”url”:”http:\/\/search.twitter.com\/search?q=%23youneedtositdown“}Here is the code:-
var url:String = _trendsView.row.url; _tweetsView.model.loadJSON(“http://search.twitter.com/search.json?q=”+url.substr(url.lastIndexOf(“/”)+1));
Notice that a UIList has a row property. This gives you the data associated with the last row that was clicked. So in the code above, we concatenate the query string from the “url” field, with ”http://search.twitter.com/search.json”.
autoLayout=”true”
Usually, MadComponents only arranges the layout of each screen when it first renders it, or when the screen orientation changes. It doesn’t change the layout when text or images are updated. But in this example, the height of the text fields depend on how much text they contain, and size of the thumbnail picture might also affect the way each row is laid out. And the position of each row, depends on where the row above it finishes. Hence we say autoLayout=”true”. Now the layout of the rows will be rearranged every time the data is updated. Another way to think about it, is that we would use autoLayout=”true” in a list, if the rows of that list are different heights.
Navigation
We used a <navigation> container in the first tutorial. We use it to contain a number of pages. So if we want to put our two lists inside a navigation container, we would write:-
<navigation> {TRENDS_VIEW} {TWEETS_VIEW} </navigation>
When we click on a list row, the navigation container will automatically change to the next page. You don’t have to do any coding to make this happen. You also automatically get a back button.
Putting it together
11. So let’s put the two pages into a navigation container. Now our application looks like this:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
public class MadTwitterTrends extends Sprite {
protected static const SMALL_TEXT:XML = <font size="12"/>;
protected static const TRENDS_VIEW:XML =
<list id="trendsView">
<model url="http://api.twitter.com/1/trends/available.json" action="loadJSON">
<name>label</name>
<url/>
</model>
</list>;
protected static const TWEETS_VIEW:XML =
<list autoLayout="true" id="tweetsView">
<model path="results"/>
<horizontal>
<imageLoader id="profile_image_url"/>
<vertical gapV="0">
<label id="from_user" alignH="fill"></label>
<label id="text" alignH="fill">{SMALL_TEXT}</label>
</vertical>
</horizontal>
</list>;
protected static const NAVIGATOR:XML =
<navigation id="navigation" rightButton="refresh">
{TRENDS_VIEW}
{TWEETS_VIEW}
</navigation>;
protected var _navigation:UINavigation;
protected var _trendsView:UIList;
protected var _tweetsView:UIList;
public function MadTwitterTrends(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, NAVIGATOR);
_trendsView = UIList(UI.findViewById("trendsView"));
_trendsView.addEventListener(UIList.CLICKED, trendsViewClicked);
_tweetsView = UIList(UI.findViewById("tweetsView"));
_navigation = UINavigation(UI.findViewById("navigation"));
_navigation.navigationBar.rightButton.addEventListener(UIButton.CLICKED, refresh);
}
protected function refresh(event:Event):void {
if (_navigation.pageNumber==0)
_trendsView.model.loadJSON();
else if (_navigation.pageNumber==1)
_tweetsView.model.loadJSON();
}
protected function trendsViewClicked(event:Event):void {
var url:String = _trendsView.row.url;
_tweetsView.model.loadJSON("http://search.twitter.com/search.json?q="+url.substr(url.lastIndexOf("/")+1));
_tweetsView.scrollPositionY = 0;
}
}
}

Notice how I’ve added a right “refresh” button to the navigation bar. The loadJSON() method takes a url parameter, but without this parameter, it reuses the url that you used previously. So loadJSON() without any parameters causes a refresh.
A Detail Page
Finally, we’re going to make a detail page that gives you some more information about a particular twitter page. This page is based on a form consisting of an image and some label text fields.
<columns id=”detail” widths=”50,100%” autoLayout=”true”> <model path=”user”/> <imageLoader id=”profile_image_url”/> <vertical> <label id=”name” alignH=”fill”/> <label id=”screen_name”>{SMALL_TEXT}</label> <label id=”location” alignH=”fill”>{SMALL_TEXT}</label> <label/> <label id=”description” alignH=”fill”>{SMALL_TEXT}</label> </vertical> </columns>
The details page web service is XML. You might want to have a look at an example it in the browser.
http://api.twitter.com/1/users/show.xml?screen_name=e2easy
(I haven’t used my twitter account for a long time). MadComponents can deal with JSON, XML, and AMF data. In my layout I’m extracting the profile_image, name, screen_name, location, and description fields.
The Finished Application
So finally, with the detail page included, and an image skin (remember tutorial 2) for the refresh button. We’re also going to add a search to the twitter list. <search field=”text”/> means that we will compare the search string that the user types in with the contents of a field called “text”. Remember, this is one of the labels in our custom renderer.
12. Our finished application looks like this:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
public class MadTwitterTrends extends Sprite {
protected static const SMALL_TEXT:XML = <font size="12"/>;
protected static const TRENDS_VIEW:XML =
<list id="trendsView">
<model url="http://api.twitter.com/1/trends/available.json" action="loadJSON">
<name>label</name>
<url/>
</model>
</list>;
protected static const TWEETS_VIEW:XML =
<list autoLayout="true" id="tweetsView">
<model path="results"/>
<search field="text"/>
<horizontal>
<imageLoader id="profile_image_url"/>
<vertical gapV="0">
<label id="from_user" alignH="fill"></label>
<label id="text" alignH="fill">{SMALL_TEXT}</label>
</vertical>
</horizontal>
</list>;
protected static const USER_DETAIL:XML =
<columns id="detail" widths="50,100%" autoLayout="true">
<model path="user"/>
<imageLoader id="profile_image_url"/>
<vertical>
<label id="name" alignH="fill"/>
<label id="screen_name">{SMALL_TEXT}</label>
<label id="location" alignH="fill">{SMALL_TEXT}</label>
<label/>
<label id="description" alignH="fill">{SMALL_TEXT}</label>
</vertical>
</columns>;
protected static const NAVIGATOR:XML =
<navigation id="navigation" rightButton="" title="Twitter Trends">
{TRENDS_VIEW}
{TWEETS_VIEW}
{USER_DETAIL}
</navigation>;
[Embed(source="images/refresh.png")]
protected static const REFRESH:Class;
protected var _navigation:UINavigation;
protected var _trendsView:UIList;
protected var _tweetsView:UIList;
protected var _detail:UIForm;
public function MadTwitterTrends() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, NAVIGATOR);
_trendsView = UIList(UI.findViewById("trendsView"));
_trendsView.addEventListener(UIList.CLICKED, trendsViewClicked);
_tweetsView = UIList(UI.findViewById("tweetsView"));
_tweetsView.addEventListener(UIList.CLICKED, tweetsViewClicked);
_detail = UIForm(UI.findViewById("detail"));
_navigation = UINavigation(UI.findViewById("navigation"));
_navigation.navigationBar.rightButton.skinClass = REFRESH;
_navigation.navigationBar.rightButtonText = "";
_navigation.navigationBar.rightButton.addEventListener(UIButton.CLICKED, refresh);
_navigation.navigationBar.backButton.addEventListener(MouseEvent.MOUSE_UP, goBack);
}
protected function refresh(event:Event):void {
if (_navigation.pageNumber==0)
_trendsView.model.loadJSON();
else if (_navigation.pageNumber==1)
_tweetsView.model.loadJSON();
}
protected function goBack(event:MouseEvent):void {
_navigation.navigationBar.rightButton.visible = true;
}
protected function trendsViewClicked(event:Event):void {
var url:String = _trendsView.row.url;
_tweetsView.model.loadJSON("http://search.twitter.com/search.json?q="+url.substr(url.lastIndexOf("/")+1));
_tweetsView.scrollPositionY = 0;
}
protected function tweetsViewClicked(event:Event):void {
var user:String = _tweetsView.row.from_user;
_detail.data = {profile_image_url:null}; //Clear the old image
_detail.model.loadXML("http://api.twitter.com/1/users/show.xml?screen_name="+user);
_navigation.navigationBar.rightButton.visible = false;
}
}
}
You can download my refresh.png image from here. Or the subversion repository. It’s in the images folder.
So that’s it. We’ve built a twitter client application for mobile. And MadComponents handled all the tricky stuff for you. Easy, wasn’t it?
What’s next ?
In the next tutorial we’re going to learn about how to build your application for mobile devices (iPhone, Android, etc.), using Adobe’s FREE command-line tools. amxmlc, and adt.
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation at http://code.google.com/p/mad-components/downloads/list
There are also lots of code examples to view or check-out from the subversion repository at http://code.google.com/p/mad-components/source/checkout
Please subscribe to this blog if you want to catch subsequent tutorials.
Having laid the foundations with the previous two tutorials, now we can start to demonstrate the real power of MadComponents for mobile flash applications. In this tutorial, we’re going to investigate lists and pickers.
There have been a few version updates since the last tutorial – So always make sure that you have the latest version of the mad components library. (Currently, the latest is madComponentsLib0_5_3.swc). Download from here.
Beware Copy and Paste
Given that these tutorials are full of XML examples, it’s worth mentioning again that things can go wrong if you copy and paste XML into Flash or Flex Builder. You might get an error that says:- “TypeError: Error #2007: Parameter text must be non-null”. This is because the pasted text contains unprintable characters that screw things up. Refer to the previous tutorial for advise of how to remedy this.
Defining Data in XML
Let’s assume that we want to build an application, where the user can scroll through a list of names. We can first define the data that will populate the list like this:-
<data> <item label=”Sneezy”/> <item label=”Sleepy”/> <item label=”Dopey”/> <item label=”Doc”/> <item label=”Happy”/> <item label=”Bashful”/> <item label=”Grumpy”/> </data>
There is also an alternative shorthand way of expressing XML data in MadComponents. Given that the names have no spaces or non-alphabetic characters, we can save some typing and write:-
<data> <Sneezy/> <Sleepy/>
<Dopey/> <Doc/> <Happy/>
<Bashful/> <Grumpy/> </data>
Making a list
To put this data into a list, we simply write:-
<list> {DATA} </list>
So, the entire program looks like this:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
public class MadLists extends Sprite
{
protected static const DATA:XML = <data>
<Sneezy/>
<Sleepy/>
<Dopey/>
<Doc/>
<Happy/>
<Bashful/>
<Grumpy/>
</data>;
protected static const LIST:XML = <list>{DATA}</list>;
public function MadLists(screen:Sprite = null)
{
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, LIST);
}
}
}
If you rapidly click and drag the list up or down, you’ll see it scroll, and the scrollbar appearing at the side. You probably want a longer list of data to really see this in action. Testing an app on the desktop, using a mouse or trackpad, it can be a bit tricky to control the difference between scroll/swipe gestures and click gestures. But on the device – it all makes sense.
Listen for clicks
Listen for list clicks as follows:-
protected var _list:UIList
_list = UIList(UI.findViewById(“list”)); _list.addEventListener(UIList.CLICKED, listClickedHandler); protected function listClickedHandler(event:Event):void { var index:int = _list.index; // var group:int = _list.group; //divided and grouped lists only. }
Divided and Grouped lists have a group property, that gives the group index of the clicked row.
Tick Lists
MadComponents has two kinds of tick list. <tickList/> and <tickOneList/>. As you’d expect, <tickOneList> only allows one row to be ticked at any time. (so click on a second row, and the first one un-ticks itself).
You can read the state of the tick list using ActionScript. When listening for the state of the data to change, listen for Event.CHANGE , rather than UIList.CLICKED.
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
public class MadTickList extends Sprite
{
protected static const DATA:XML = <data>
<Sneezy/>
<Sleepy/>
<Dopey/>
<Doc/>
<Happy/>
<Bashful/>
<Grumpy/>
</data>;
protected static const TICKLIST:XML = <tickList id="ticks">{DATA}</tickList>;
protected var _tickList:UITickList;
public function MadTickList(screen:Sprite = null)
{
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, TICKLIST);
_tickList = UITickList(UI.findViewById("ticks"));
_tickList.addEventListener(Event.CHANGE, tickListChanged);
}
protected function tickListChanged(event:Event):void {
trace();
for each(var item:uint in _tickList.tickIndexes) {
trace(UILabel(_tickList.findViewById("label",item)).text);
}
}
}
}
Defining Grouped Data in XML
Now, we’re going to look at grouped lists in MadComponents. But first, let’s look at how to define grouped data.
<data> <group label=”dwarfs”> <Sneezy/> <Sleepy/>
<Dopey/> <Doc/> <Happy/>
<Bashful/> <Grumpy/> </group> <group label=”reindeer”> <Dasher/> <Dancer/> <Prancer/> <Vixen/> <Comet/> <Cupid/> <Donder/> <Blitzen/> </group> </data>
You can still use the alternative notation, for example: <item label=”Dasher”/> if you wish. Group label attributes above are optional. Include them if you require group headings on your grouped list.
Divided and Grouped Lists
You can create a divided list as follows:-
<dividedList> {GROUPED_DATA} </dividedList>
Or, create a grouped list like this:-
<groupedList> {GROUPED_DATA} </groupedList>
But we can improve the appearance of the grouped list, by choosing appropriate colours and spacing:-
<groupedList background=”#C6CCD6″ colour=”#CCCCCC” gapH=”32″ gapV=”4″> {GROUPED_DATA} </groupedList>
Colouring Lists
In the previous example, we used the colour, and background attributes to change the appearance of a list. This works for any list. Not just the grouped list.
The colour attributes defines the colours of the dividing lines. The background attribute can specify several colour values, separated by commas. The first parameter is the background colour, the second is the row colour. Any further parameters allow you to have rows with alternating colours. For example:-
<list colour=”#333366” background= ”#CCCCFF,#9999CC,#AAAACC”>
Creates the following result:-
Suppose you also want to make the text colour white. You can define <text> formatting as follows:-
<list colour=”#333366″ background= “#CCCCFF,#9999CC,#AAAACC”> {DATA} <font color=”#FFFFFF”/> </list>
Notice that colour attribute inside an HTML font tag has American spelling. But Colour elsewhere in the layout is spelt with a ‘u’, with British spelling.
Custom renderers
You can define a custom list item renderer in XML. Suppose, for example, each row contains a label and a switch. You can define that as follows:-
<list colour=”#333366″ background= “#CCCCFF,#9999CC,#AAAACC”> {DATA} <horizontal> <label id=”label”/> <switch id=”state” alignH=”right”/> </horizontal> </list>
Searching Lists
The <search> tag may be used to create a search bar at the top of a list. The field attribute can be used to enable searching and filtering of the list, without having to write any actionScript. In the previous “dwarfs” list example, you can modify the layout as follows to enable searching:-
<list> {DATA} <search field=”label”/> </list>
Setting data in ActionScript
You can set list data from ActionScript, rather than defining it in XML. You can assign either an array, or XML. You can assign an array of objects to the data property like this:-
list.data = [{label:”one”}, {label:”two”}, {label:”three”}];
There is also a short way to do this, using an array of strings.
list.data = [“one”,”two”,”three”];
For a custom renderer, you might have more than one value in each object, for example:-
list.data = [{label:”one”,switch:"on"}, {label:”two”,switch:"off"}, {label:”three”,switch":on"}];
For a divided, or grouped list, use a two dimensional array:-
list.data = [[{label:”one”}, {label:”two”}], [{label:”three”}]];
You can assign XML data like this:-
list.xmlData = <data><one/><two/><three/></data>;
Or this:-
list.xmlData = <data><i label=”one”/><i label=”two”/></data>;
For a divided or grouped list, we would do something like this:-
list.xmlData = <data><group> <one/><two/></group> <group><three/> </group></data>;
Pickers

The <picker> component tends to be used in conjunction with a <columns> layout. The column layout was described in the first tutorial.
Here is an example a three column picker:-
<columns gapH=”0″ widths=”40,50%,50%” pickerHeight=”200″> <picker alignH=”centre”> {NUMBERS} </picker> <picker> {DATA} </picker> <picker> {DATA} </picker> </columns>
The pickerHeight attributes enabled you to declare the height of the picker bank.
Here’s a complete code example of using a picker bank:-
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
public class MadComponentsPicker extends Sprite {
protected static const DATA:XML = <data>
<Red/>
<Orange/>
<Yellow/>
<Green/>
<Blue/>
<Indigo/>
</data>;
protected static const PICKER_EXAMPLE:XML = <columns gapH="0" widths="40,50%,50%" pickerHeight="180">
<picker alignH="centre">
<data>
<item label="0"/>
<item label="1"/>
<item label="2"/>
<item label="3"/>
<item label="4"/>
<item label="5"/>
<item label="6"/>
<item label="7"/>
<item label="8"/>
<item label="9"/>
</data>
</picker>
<picker index="1">
{DATA}
</picker>
<picker index="4">
{DATA}
</picker>
</columns>;
public function MadComponentsPicker(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, PICKER_EXAMPLE);
}
}
}
Notice the index attributes in the XML, that set the pickers to initial preset positions.
What’s next ?
In the next tutorial we’re going to learn about navigation, connecting MadComponents to server data, and we’ll build a Twitter application.
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation at http://code.google.com/p/mad-components/downloads/list
There are also lots of code examples to view or check-out from the subversion repository at http://code.google.com/p/mad-components/source/checkout
Please subscribe to this blog if you want to catch subsequent tutorials.
In the first tutorial, we built a simple two page application with a button on each page, which triggered a page change. The tutorial was an interpretation of “Build a mobile app in five minutes“. But instead of building the project in Flash Builder 4.5, we built it using MadComponents. It is recommended to read the previous tutorial to get the most out of this tutorial.
MadComponents is IDE agnostic. So you can build mobile projects in Flash, or Flex (Flash Builder), or third-party Flash Platform tools.
In this tutorial, we’re going to learn about images, skinning, and nine patch images in MadComponents.
This tutorial assumes you have version MadComponentsLib0_5_1.swc or a later version. Download it from http://code.google.com/p/mad-components/downloads/list
The image tag
We can include images into a MadComponents layout using the <image> tag. For example:-
<image>{getQualifiedClassName(PICTURE64)}</image>
This layout just includes the image class “PICTURE64″ into your layout. getQualifiedClassName is an Adobe utility that coverts a Class reference to a textual representation. Here is the complete program:-
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.utils.getQualifiedClassName;
import com.danielfreeman.madcomponents.*;
public class MadImage extends Sprite
{
[Embed(source="images/picture64.png")]
protected static const PICTURE64:Class;
protected static const IMAGE:XML = <image>{getQualifiedClassName(PICTURE64)}</image>;
public function MadImage(screen:Sprite = null)
{
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, IMAGE);
}
}
}
picture64 is your own .png image file. (Assumed to be 64×64 pixels). We assume we’ve put in in a folder called images.
Beware Copy And Paste
The following general advice isn’t only applicable to MadComponents project. It is a general issue, that can affect any project.
Copying and pasting into Eclipse, or Flash can cause inexplicable errors in your code. Especially code that has XML. Working through a tutorial such as this, you’re likely to copy and paste. The problems are caused by unprintable characters in the pasted code. They look like spaces, or linefeeds, but they’re not. And they screw things up. If this happens, one way you can fix things is to delete all the spaces and linefeeds, and then reformat your code or layout xml. Single, and double quote characters can also cause problems. There are several versions of these characters, that look very similar – but the wrong character will cause a syntax error.
MadComponents provides a utility, UI.clean() that removes unwanted unprintable characters in XML layouts.
Instead of writing this:-
UI.create(this, LAYOUT);
Write this:-
UI.create(this, UI.clean(LAYOUT));
The reason that clean isn’t employed usually, is that there is an overhead to doing this. If you run into problems, it is better to try and delete spaces, linefeeds, and reformat. But UI.clean() is an easy thing to do if you run into copy paste problems during development. And it can help eliminate this as a possibility when debugging your code.
Set image from ActionScript
You can use an image tag to define an empty placeholder for an image that you assign in ActionScript. For example, here is an placeholder for an image 64 pixels by 64 pixels:-
<image id=”myimage”>64</image>
If you specify one number, the placeholder is assumed to be square. But specify two numbers for a rectangular place holder, for example, 30 pixels (width) by 40 pixels (height):-
<image id=”myimage”>30,40</image>
To assign an image to this placeholder, use the following code:-
var myImage:UIImage = UIImage(UI.findViewById(“myimage”));
myImage.imageClass = PICTURE64; //Where this is the embedded Class from before.
Or you can write:-
myImage.imageClassName = getQualifiedClassName(PICTURE64);
If the placeholder size is smaller than the image size, then MadComponents will scale the image down to fit.
You can also set the image from a bitmap instance. This is convenient for developers using Flash, as they can utilise an image that they’ve set up in their library.
myImage.image = bitmapValue; //From Flash Library.
You can assign any DisplayObject subclass instance to the image property.
myImage.image = anyDisplayObjectSubclassInstance;
Suppose you want to assign a different image to a placeholder, depending on the screen density of the device. You might do something like this:-
var dpi:uint = Capabilities.screenDPI;
if (dpi>280)
myImage.imageClass = PICTURE64_320;
else if (dpi>200)
myImage.imageClass = PICTURE64_240;
else
myImage.imageClass = PICTURE64_160;
Here is an example with an image that changes every time you click on it. (Make sure you have MadComponentsLib0_5_1.swc or higher)
package
{
import com.danielfreeman.madcomponents.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.utils.getQualifiedClassName;
public class MadImage extends Sprite
{
[Embed(source="images/mp3_48.png")]
protected static const MP3:Class;
[Embed(source="images/mp4_48.png")]
protected static const MP4:Class;
protected static const IMAGE:XML = <image id="myImage" alignH="centre" alignV="centre">
{getQualifiedClassName(MP3)}
</image>;
protected var _myImage:UIImage;
protected var _toggle:Boolean = true;
public function MadImage(screen:Sprite = null)
{
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, IMAGE);
_myImage = UIImage(UI.findViewById("myImage"));
_myImage.addEventListener(MouseEvent.MOUSE_UP,clicked);
_myImage.mouseEnabled = true;
}
protected function clicked(event:MouseEvent):void {
_toggle = !_toggle;
_myImage.imageClass = _toggle ? MP3 : MP4;
}
}
}
ImageLoader
We can use an <imageLoader> to obtain an image from the server. For example:-
<imageLoader>http://www.myserver.com/myImage.jpg</imageLoader>
We can also define a placeholder.
<imageLoader id=”myImage”>40,30</imageLoader>
Control the <imageLoader> from ActionScript, as follows:-
var myImage:UIImageLoader = UIImageLoader(UI.findViewById(“myimage”));
myImage.value = “http://www.myserver.com/myImage.jpg”;
You can set up listeners on the UIImageLoader instance for Event.COMPLETE, SecurityErrorEvent.SECURITY_ERROR, IOErrorEvent.IO_ERROR, and ErrorEvent.ERROR.
Nine Patch Images
MadComponent buttons are skinnable. We can use utilise a snazzy button design in the form of a .jpg, or .png image. The size of the button may vary, for different screens, and depending on device orientation. So the skin image must be resizable. But when you resize an image, this can cause problems with pixelation and distortion of the bitmap. The solution to the problem is called a “nine patch image”. Some Flash developers reading this tutorial will be familiar with the concepts of nine patch images, but if you’re not – keep reading.
Suppose we have a snazzy button image:-

Now let’s resize the image vertically.

Now our button doesn’t look so snazzy any more. The curved corners, and the corners of the highlight area are irregular and stretched. There is a beveled area around the button, that’s looking very fat at the sides. And I’m beginning to see pixelation raggedness on the curves.
Here is the same image vertically stretched, but this time, we’ve used a nine patch scheme:-

See the difference? So how does nine patch scaling work?
We divide the image into nine regions. Each region has different scaling rules.

In the corners (1, 3, 7 and 9 ) there is no scaling. The sides ( 4 and 6 ) are only scaled vertically. The top and bottom ( 2 and 8 ) are only scaled horizontally. The centre ( 5 ) is scaled both horizontally and vertically.
We apply the nine patch to the red button image as show:-

The curved corners aren’t scaled, so their shapes are preserved. The sides are scaled so that the bevel doesn’t get fat, and the highlight area of the button doesn’t get any taller.

In ActionScript, you can define a nine patch embedded image like this:-
[Embed(source="images/red.png",
scaleGridTop="100", scaleGridBottom="200",
scaleGridLeft="40", scaleGridRight="200")]
protected static const RED:Class;
Where scaleGridTop, scaleGridBottom, scaleGridLeft, and ScaleGridRight are the positions of the dividing lines of the nine patch (from the top-left corner).
Skinning a button
You can apply this nine patch image skin (or just a normal image) to a button within the layout like this:-
<button skin={getQualifiedClassName(RED)}>hello</button>
To set the height of a skinned button, you can use the height attribute:-
<button skin={getQualifiedClassName(RED)} height=”100″>hello</button>
You can also set a button skin in ActionScript:-
var button:UIButton = UIButton(UI.findViewById(“button”));
button.skinClass = RED;
//or
button.skin = getQualifiedClassName(RED);
button.skinHeight = 100.0;
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation at http://code.google.com/p/mad-components/downloads/list
Please subscribe to this blog if you want to catch subsequent tutorials.
What’s next?
So far, we’ve barely scratched the surface of MadComponent’s capabilities. In the next tutorial, we’ll be talking about lists and pickers. Then we’ll build a Twitter client like the one described in this Flash Builder 4.5 tutorial. But using MadComponents, it will be much, much easier than Flash Builder.
MadComponents. Easier than Flash Builder 4.5?
In my previous post, I made comparisons between Flash Builder 4.5 and MadComponents for mobile applications. Inevitably, the ActionScript + MadComponents app was much smaller than the same app written using Flash Builder.
App size is a big deal for mobile apps. It’s a big deal for Adobe, who are already battling negative perceptions about the performance of the Flash Platform on mobile. Particularly on the iPhone.
So does Flash Builder make up for it in other ways? Does it simplify the development process?
I don’t believe it does. But obviously I’m biased, as I created MadComponents. So don’t take my word for it. Take a look at my MadComponents examples at http://code.google.com/p/mad-components/source/browse/ . Or try these tutorials, that guide you though using MadComponents from first principles – and judge for yourself.
Even though MadComponents doesn’t have a visual drag-and-drop UI builder (I don’t have time to write one) – expressing something in MadComponents XML markup language is often equivalent to significant fiddly coding in Flex. MadComponents is more than just lightweight mobile components, it simplifies communication with the server too. ( More about that in later tutorials. )
These tutorials are based on Adobe’s “Getting Started With Flex On Mobile” tutorials at:- http://www.adobe.com/devnet/flex.html. I’ll be describing about how to do each of the mobile exercises using MadComponents. So if you like, you could work through both tutorials, and decide which suits you best. MadComponents or Flash Builder.
MadComponents is IDE agnostic. You can use Flash Builder (Flex), or Flash, or a third-party IDE such as AXDT, or Flash develop. I deliberately restricted myself to SDK4.0 capabilities. And I didn’t use any AIR-only classes. This means that MadComponents is incredibly portable. You don’t need the latest IDE, or the latest SDK, or AIR runtime. You can test or deploy a MadComponents application to the browser if you wish. I tend to work this way – restricting myself to core flash platform features to develop a ubiquitous application that will run “anywhere”. Only adding specific AIR functionality, as a separate, and optional extensions – for desktop, or mobile deployment, at the end.
MadComponents Layouts
MadComponents has its own XML layout language. A layout will be a familiar concept to anyone who has used HTML, MXML, native Android development, or Java Swing. The advantage of an XML layout is that it expresses how the UI is arranged irrespective of screen size, orientation and pixel density. MadComponents deals with this nitty gritty – you don’t have to.
This is how you express a label, and a button, arranged vertically:-
<vertical> <label>Hello, World!</label> <button>Continue</button> </vertical>
Suppose you wanted to arrange things horizontally. You’d write:-
<horizontal> <label>Hello, World!</label> <button>Continue</button> </horizontal>
Let’s take this one step further, and improve the formatting.
<columns alignH=”fill”> <label>Hello, World!</label> <button>Continue</button> </columns>
Now the label, and the button, are each allocated half of the screen width. But let’s change the components, so we can see their widths more clearly, and also change the ratios of the columns:-
<columns alignH=”fill” widths=”30%,30%,40%”> <input/> <button/> <slider/> </columns>
Now we have three columns, and a custom ratio of widths. Widths can also be specified in absolute pixels. For example, widths=”90,40%,60%”. Absolute pixel measurements are allocated first. The input field will be 90 pixels wide. Note there is no “%” sign after 90 – so it means 90 pixels. Not 90 percent. After all the pixel measurements are allocated, then the relative, percentage widths are allocated. The button will take up 40% of the remaining width, and the slider will take up the last 60%.
If you wish to change the spacing between columns, you can use the gapH attribute. (Or gapV attribute vertically).
<columns alignH=”fill” widths=”30%,30%,40%” gapH=”20″> <input/> <button/> <slider/> </columns>
There is no padding attribute in MadComponents Layout. If you wish to insert padding, you can use an <image/> component within the layout, and specify its size. for example:-
<image>30,40</image>
Where 30 is the width, and 40 is the height.
The Hello World Example
So let’s get started with “Build a mobile app in five minutes“. The following instructions are appropriate whether you’re using Flash or Flex. What the tutorial demonstrates is how to make an application with two pages, where you can click on buttons to switch between the pages.

Downloads
If you need to peek at the answers at the back of the book, go ahead.
Flash users can download the project from http://code.google.com/p/mad-components/downloads/list . To run this Hello World example, just follow steps (2A) and (7) below. Changing the call from “MadComponents” to “MadHelloWorld”.
Flex (Flash Builder) users can check-out the MadComponents demos from the Subversion repository at: http://code.google.com/p/mad-components/source/checkout . MadHelloWorld.as is the example for this tutorial.
Hello World Step by Step
Whether or not you’ve jumped ahead to see the final result – here are the step by step instructions:
1. If you don’t have the latest version of MadComponents, you can download it from http://code.google.com/p/mad-components/downloads/list
You’ll need MadComponentsLib0_5.swc (or a newer version when available).
2A. If you’re using Flash. You need to find your libs folder. For Flash CS5, you’ll find this directory at the following path, from your Flash application folder:-
Adobe_Flash_CS5/Common/Configuration/ActionScript_3.0/libs
Once you’ve found this folder, put MadComponentsLib into it:-

2B. If you’re using Flash Builder (Flex), just include the .swc into the project in the usual way.
( Project -> Properties -> ActionScript Build Path -> Library Path -> Add SWC Folder… lib )


3. Create a new ActionScript application. Call it “MadHelloWorld”. Either Adobe AIR ActionScript applications, or a browser based application.
4. For an Adobe AIR application, set your window size to 300 x 454. (not applicable to a browser application). In Flash, you’ll see this in the properties panel:-
( On a real device, it will adapt to the screen size, but in simulation – it assumes 300 x 454 pixels )
5. Now save your application. In Flash, make sure you’ve made a new folder for it.
6. In Flex, you’ll already have a top ActionScript class. In Flash you’ll need to create one. File->New->ActionScript File. Call it “MadHelloWorld.as”. Save it in the same folder as MadHelloWorld.fla .
7. In Flash, create a link between the timeline project, and the ActionScript file. (No need to do anything in Flex). Click on the first cell on the timeline, and in the Actions Panel, type:
new MadHelloWorld(this);

8. Now you’re ready to write some code. Let’s start with the first layout example, and generate the UI for this XML using the UI.create() method.
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import com.danielfreeman.madcomponents.*;
public class MadHelloWorld extends Sprite {
protected static const HOME_VIEW:XML = <vertical>
<label>Hello, World!</label>
<button>Continue</button>
</vertical>;
public function MadHelloWorld(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, HOME_VIEW);
}
}
}
Note the code setting stage.align and stage.scaleMode. This isn’t a MadComponents thing, just a standard pure ActionScript thing to ensure no scaling, and aligning the corner of the app to the corner of the screen.
This example creates a label and a button. But we want to put them in the centre of the screen.
9. Add alignH and alignV attributes to the layout. Note the British spelling “centre”.
<vertical alignV=”centre”> <label alignH=”centre”>Hello, World!</label> <button alignH=”centre”>Continue</button> </vertical>
10. That’s better, and we can create the second page in a similar way. For now, just replace the layout, for the layout of the second page, to see what it will look like:-
<vertical alignV=”centre”> <label alignH=”centre”> Success!</label> <button alignH=”centre”>Back</button> </vertical>
11. Now we need to make a layout that includes both pages. Because the Flash Builder has a title bar at the top, we’re going to use a Navigation container. We call it a “container” because it contains one or more pages.
<navigation title=”HomeView”> {HOME_VIEW} {MY_NEW_VIEW} </navigation>
The curly braces {} provide a convenient way to split up the layout definition into manageable, readable, small chunks of XML. So with both pages inside a Navigation container our code looks like this:-
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import com.danielfreeman.madcomponents.*;
public class MadHelloWorld extends Sprite {
protected static const HOME_VIEW:XML = <vertical alignH="centre" alignV="centre" width="100">
<label alignH="centre">Hello, World!</label>
<button id="forward" alignH="fill">Continue</button>
</vertical>;
protected static const MY_NEW_VIEW:XML = <vertical alignH="centre" alignV="centre" width="100">
<label alignH="centre">Success!</label>
<button id="back" alignH="fill">Back</button>
</vertical>;
protected static const NAVIGATOR:XML = <navigation title="HomeView">
{HOME_VIEW}
{MY_NEW_VIEW}
</navigation>;
public function MadHelloWorld(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, NAVIGATOR);
}
}
}
I’ve made a small change to the way things are placed in the centre of the screen. This was to make buttons the same size.
12. When we run the above example, we see the first page. But clicking on the button has no effect. We need to set up a listener, and a handler that tells the navigation container to display the second page.
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import com.danielfreeman.madcomponents.*;
public class MadHelloWorld extends Sprite {
protected static const HOME_VIEW:XML = <vertical alignH="centre" alignV="centre" width="100">
<label alignH="centre">Hello, World!</label>
<button id="forward" alignH="fill">Continue</button>
</vertical>;
protected static const MY_NEW_VIEW:XML = <vertical alignH="centre" alignV="centre" width="100">
<label alignH="centre">Success!</label>
<button alignH="fill">Back</button>
</vertical>;
protected static const NAVIGATOR:XML = <navigation id="navigation" title="HomeView" leftArrow="">
{HOME_VIEW}
{MY_NEW_VIEW}
</navigation>;
protected var _navigation:UINavigation;
public function MadHelloWorld(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, NAVIGATOR);
_navigation = UINavigation(UI.findViewById("navigation"));
var forward:UIButton = UIButton(UI.findViewById("forward"));
forward.addEventListener(UIButton.CLICKED, goForward);
}
protected function goForward(event:Event):void {
_navigation.goToPage(1);
}
}
}
In the example above, we set up a reference to objects in the user interface. Notice that in the layout, we’ve given the navigation, and the button ‘ids’. id=”navigator” and id=”forward”. In the ActionScript, we can refer to these ids, using UI.findViewById(). Now we can set up listeners, or refer to their methods or properties.
We set up a listener to detect clicks on the button:-
forward.addEventListener(UIButton.CLICKED, goForward);
And within the goForward handler, we tell the navigator to display the second page (we start counting pages at 0, so the second page is page 1).
_navigation.goToPage(1);
The navigation container automatically gives you a back button on the title bar. So we can switch back to the first page. So now we have a two page example. But it’s not quite like the one in the FB4.5 tutorial.
13. We want to add three more features to complete the example above.
We want the back button in the centre of the screen to work. We set up a listener and a handler just like we did before. But this time, we’ve added transition to the page change. UIPage.SLIDE_LEFT and UIPage.SLIDE_RIGHT
We want to get rid of the back button on the title bar. By setting the text of this button to the empty string, leftArrow=”" ,it disappears.
And we want to change the, depending which page we’re on. So within the handlers, we set _navigation.title.
Here is the updated code:-
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import com.danielfreeman.madcomponents.*;
public class MadHelloWorld extends Sprite {
protected static const HOME_VIEW:XML = <vertical alignH="centre" alignV="centre" width="100">
<label alignH="centre">Hello, World!</label>
<button id="forward" alignH="fill">Continue</button>
</vertical>;
protected static const MY_NEW_VIEW:XML = <vertical alignH="centre" alignV="centre" width="100">
<label alignH="centre">Success!</label>
<button id="back" alignH="fill">Back</button>
</vertical>;
protected static const NAVIGATOR:XML = <navigation id="navigation" leftArrow="" title="HomeView">
{HOME_VIEW}
{MY_NEW_VIEW}
</navigation>;
protected var _navigation:UINavigation;
public function MadHelloWorld(screen:Sprite = null) {
if (screen)
screen.addChild(this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
UI.create(this, NAVIGATOR);
_navigation = UINavigation(UI.findViewById("navigation"));
var forward:UIButton = UIButton(UI.findViewById("forward"));
forward.addEventListener(UIButton.CLICKED, goForward);
var back:UIButton = UIButton(UI.findViewById("back"));
back.addEventListener(UIButton.CLICKED, goBack);
}
protected function goForward(event:Event):void {
_navigation.goToPage(1,UIPages.SLIDE_LEFT);
_navigation.title = "MyNewView";
}
protected function goBack(event:Event):void {
_navigation.goToPage(0,UIPages.SLIDE_RIGHT);
_navigation.title = "HomeView";
}
}
}
So that’s it. An application with two pages, where clicking on buttons causes the page to change.
14. Finally, let’s just play around with colour. We can specify the colour of the application, using the colour attribute. For example, make the following change:-
<navigation id=”navigation” leftArrow=”" title=”HomeView” colour=”#334433″>
This colour setting will actually cascade through the XML description, and the buttons will inherit this colour from the navigation controller. If you want to make a button a different colour, you can so this:-
<button id=”forward” alignH=”fill” colour=”#CC9933“>Continue</button>
If you want to change the background colour, you can use the stageColour attribute:-
<navigation id=”navigation” leftArrow=”" title=”HomeView” colour=”#334433″ stageColour=”#EEFFEE”>
But the Flash Builder tutorial, goes one step further than just changing the colour of components. It shows you how to skin the buttons. MadComponents can do this too. But we’ll talk about how to do that in the next tutorial.
Further reading
To find out more about MadComponents, you can read the other related threads on this blog, or download the documentation at http://code.google.com/p/mad-components/downloads/list
Please subscribe to this blog if you want to catch subsequent tutorials.







