Skip to content
December 5, 2011 / Daniel Freeman

10 new MadComponents features

I haven’t had the time to blog about MadComponents lately.  But I’ve still been developing and refining it whenever I get a few spare moments. ( MadComponents is an increasingly popular, open-source, powerful yet lightweight, pure-actionscript mobile app framework. )  You’ll find the latest version here.  I’ve implemented some new features in response to developer requests.  But most were driven by perfectionism.  At this stage of development, having achieved maturity and stability with the framework, the latest updates and features are all about the finer details.  (So if this your first encounter with MadComponents, it is better to start with a more general explanation.)

So here’s a rundown of 10 new features:-

1. <navigationPages>

To keep MadComponents lightweight, I’d decided not to add any new components to it.  But <navigationPages> implements such a common requirement, that I moved <scrollXY> out of the library to make room for it.

Suppose we have a navigation based application, with a list view and a detail page.  Let’s assume each list row, loads in a different detail page.  Clicking on the first list row, shows the first detail page, clicking on the second list row, shows the second detail page, and so on.  This is such a common UI pattern, that I’d already written this example showing developers how to do it.

Now <navigationPages> makes this UI pattern even easier, with no extra programming required.  Simply arrange the layout XML like this:-

<navigationPages>
   {LIST}
   {PAGE0}
   {PAGE1}
   {PAGE2}
</navigationPages>

There’s an example on the Google code site. <navigationPages> can be nested. For cascading menus, see the example here.

 

2. Alternative <switch> style

If you write <switch alt=”true”/>, it renders a curved appearance for the switch.

 

3. <model> parse attribute

The <model> tag is one of MadComponent’s most powerful features.  It enables the user interface to communicate with a web server, and fetch data using XML, JSON, or AMF.  Suppose we’re writing an RSS reader.

The schema for RSS XML data looks like this:-

<rss>
   <channel>
      <item>
         data in here
      </item>
      <item>
          data in here
      </item>
etc... etc...

We’re interested in the XML information inside <item> packets.  Notice that to get to <item>, we first need to go through <rss>, and <channel>.  For each list row, we just want <title>, <pubDate>, and <description> for our app.  We can describe the schema more concisely like this:-

<rss>
   <channel>
      <item>
         <title/>
         <pubDate/>
         <description/>
      </item>
   </channel>
</rss>

So let’s put all the pieces together, and show how the list is made.

<list autoLayout="true">

<model url="http://rss.cnn.com/rss.edition.rss" action="loadXML">
      <rss>
         <channel>
            <item>
                <title/>
                <pubDate/>
                <description/>
            </item>
         </channel>
     </rss>
   </model>

   <vertical alignH="fill">
      <label id="title"/>
      <label id="pubDate"/>
      <label id="description"/>
   </vertical>

</list>

Notice that within the model tag, we’ve described both the url of the rss feed, and an action.  loadXML.  Within the list itself, we’ve specified autoLayout=”true”.  This is because each row of our list will be a different height, depending on how much text it contains.

The XML above may look simple, but in fact, it can be simplified even further.  This is where the parse attribute comes in.  We don’t have to write the schema out in full.  We can just write this:-

<list autoLayout="true">
   <model url="http://rss.cnn.com/rss.edition.rss" action="loadXML" parse="rss.channel.item"/>
      <vertical alignH="fill">
         <label id="title"/>
         <label id="pubDate"/>
         <label id="description"/>
      </vertical>
</list>

(Note: that the model path attribute is now depreciated).

4. parse wildcards

When parsing a JSON feed, if you leave out a tag name within a parse attribute, that missing name is treated as a wildcard, and it will match any key name during the parse.

Why is this useful?

Take a look at some JSON data for a twitter trends feed ( http://api.twitter.com/1/trends/daily.json ):-

{"trends":{"2011-12-03 15:20":[{"name":"#TwoThingsThatNeverMix","query":"#TwoThingsThatNeverMix"...

Notice “2011-12-03 15:20” ?  That’s a date stamp.  It is also a key value that will be different every time.  So we can’t write a schema for this feed, because it’s always going to change.  In my opinion, a Twitter feed shouldn’t have been designed like this, with a changing key value.  But we can solve this problem and employ a wildcard.  parse=”trends.”.  The dot at the end, means that the next key value to matched to whatever comes next, so the date stamp is skipped.

( The complete twitter trends example is here )

5. Helper methods

The model class contains two static helper methods that can be useful when dealing with online data:-

Model.queryString()  Will remove extended characters from a string, and then escape it, converting it into a valid URL query string.

Model.htmlDecode()  Will convert special XML encodings such as &amp; to their corresponding characters.

6. XML data

We can specify XML data for multiple fields.  For example:-

<data>
   <item firstname="Fred" lastname="Bloggs"/>
   <item firstname="Sarah" lastname="Wilson"/>
   <item firstname="Peter" lastname="Potter"/>
</data>

(Previously, we could only specify a single field for each XML item ).

7. Concatenating Fields

Let’s suppose you were connected to an XML feed supplying firstnames, and surnames, and you wish to display these in a list.  Concatenate the firstname, to the surname, with a space between.  We can accomplish this by mapping both fields to the same component.  For a list without a custom renderer, the default UILabel has an id named “label”.  Here’s an example:-

<list>
   <model url={URL} action="loadXML">
      <root>
         <item>
            <firstname>label</firstname>
            <surname>label</surname>
         </item>
      </root>
   </model>
</list>

 

8. loadXML(), loadJSON(), and loadAMF() API changes

I haven’t got around to updating the class documentation yet, but the Model APIs all have an extra optional parameter that allows you to set further options for the URLRequest or NetConnection.  One possible use of this parameter is the ability to set log-in details for a secure web site.

Here are the method headings:-

public function loadXML(url:String = "", request:URLRequest = null):void
public function loadJSON(url:String = "", request:URLRequest = null):void
public function loadAMF(url:String = "", service:String = "", parameters:Array = null, netConnection:NetConnection = null):void

9. sortBy and sortMode attributes

The list sortBy attribute now allows a list to be sorted by more than one field.  For example:-

<list sortBy="surname,firstname">

The sortMode parameter allows each sortBy field to be sorted according to different criteria.  For example:-

<list sortBy="date" sortMode={[Array.DESCENDING | Array.NUMERIC]}/>
<list sortBy="surname,firstname" sortMode={[0,Array.CASEINSENSITIVE]}/>

( 0 is the default mode.  Ascending )

10. Cascading Styles

I’ve had a few queries lately regarding styling.  This isn’t really a new feature, and it is really more of an ActionScript trick than a feature of MadComponents.

MadComponents are very customisable using the colour and background attributes. Also the skin attribute for a button. For many components (Button, Label, Lists, Picker, etc.), you can also specify the text style as HTML. Eg. <font size=”20″ color=”#CCCCFF”/>.

Other attributes such as the size (width, height) and its positioning (alignH, alignV, gapH, gapV) aren’t considered as styles, because they’re more to do with the layout, which will adapt to the screen size of the device.

Define all the styles in XML at the top, or in a Styles class. For example:-

public static const LIGHT_BLUE:XML = <font size=”20″ color=”#FFCCCC”/>;
public static const BUTTON_STYLE:String = “#9999CC,#EEEEFF,#EEFFEE,40″;

Wherever you need to apply styles, you do this kind of thing:-

public static const BUTTON:XML =
   <button background={MyStylesClass.BUTTON_STYLE}/>
      {MyStylesClass.LIGHT_BLUE}Press Me
   </button>;

(Assuming you’ve defined all your styles in MyStylesClass)

Postscript: A couple more features…

I’ve also added a backToExit attribute to <navigation>, so that the Android back button will close the application if you’re on the first page.

<navigation backToExit="true">

In version 0.6.7, I’ve added an includeInLayout property to components.  Used in conjunction with visible, this can make a component invisible, but also collapse the UI around it.  But, you need to refresh the layout for it to take effect (for which autoLayout for the container must be true).  For example:-

<vertical id="form" autoLayout="true">
   <button>button0</button>
   <button id="button1">button1</button>
   <button>button2</button>
</vertical>
var button1:UIButton = UIButton(UI.findViewById("button1"));
var form:UIForm = UIForm(UI.findViewById("form"));
button1.includeInLayout = button1.visible = false;
form.data = {};  // forces re-render due to autoLayout="true"

I decided also to provide a helper method of UIForm to simplify the above:-

var form:UIForm = UIForm(UI.findViewById("form"));
form.includeComponent("button1",false); // true = include, false = remove

( You don’t need autoLayout=”true” for this helper method )

 

 

Help Spread the Word or Get Involved

I’ve contributed MadComponents freely to the AIR Mobile developer community.  Please give something back if you can.  There’s lots of things I need help with now.  For example:-

1. Always report any bugs or shortcomings you come across.  I can usually remedy these quickly.

2. Let me know what you do with MadComponents.  If you use it to build enterprise apps, or make something for the app-store – let me know.  I’d like to showcase success stories to promote this framework.

3. Please help spread the word about MadComponents and ExtendedMadness, by blogging and twittering.

4. It would be great if you could contribute more examples and tutorials, or even just talk about these libraries and what they can do.

5. People have asked if I can make an interactive web-based MadComponents (kitchen-sink) demo.  Does anyone have the time to make and host one of these?

6. Can someone blog about using MadComponents with an MVC framework such as RobotLegs?  Or write some tutorials?

7. There may be a problem with AMF.  I’m not sure I have the AMF expertise to sort it out.  If you take a look at these discussions in the comments, perhaps you can investigate the issue, and suggest a patch, or workaround for this problem?  Or maybe we need someone to write more AMF tutorials.

8. I pointed the way about how to make Flex wrappers for MadComponents.  But I’m much more into the pure-actionscript approach myself.  Does anyone want to pick up the Flex wrappers, improve, extend, and maintain them?

9. How about applying the lightweight MXML technique to the Flex wrappers?

http://dgrigg.com/blog/2010/04/28/alpha-release-of-skinnable-minimal-components/

http://dgrigg.com/blog/2010/04/12/when-flex-goes-on-a-slimfast-diet/

Advertisements

One Comment

Leave a Comment
  1. Felipe Murguia / Dec 19 2011 8:39 pm

    I have problems with adobe flash player last version and i cant work youtube etc.

To discuss MadComponents/MC3D, join the Facebook group!

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: