FLEX RSS Widget Tutorial
The RSS tutorial will display some of the more advanced features of the wAPI. In this lesson, you will have a fully functioning RSS Flex Widget with additional tracking and user preferences.
Requirements
- Knowledge of Actionscript 3 and Flex 2
- Flex SDK (available free: download)
- Download the source code for this example here: Samples.
Steps
1. Create a new .mxml document
The first step in this tutorial is to open create a new flex mxml file for your widget. You can use your favorite text editor or Flex IDE.
2. Create the mxml application code
This will be the main application for the widget
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="300" initialize="onLoad()" backgroundAlpha="0"> </mx:Application>
3. Initialize the wAPI when the application initializes
In this step, you will add <mx:Application ... initialize="onLoad()" ... and initialize access to the widget container runtime. Create a <mx:Script> tag and add an event handler function onLoad() as shown below.
The main difference with using Flex and the yourminis wAPI is that the initialize="onLoad()" event handler needs to be added to your flex application.
Basic Widget API Flex code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="300" height="300" initialize="onLoad()" backgroundAlpha="0">
<mx:Script>
<![CDATA[
public var widget:Object; //Widget
public function onLoad():void
{
addEventListener("widget-loaded",onWidgetLoaded);
}
public function onWidgetLoaded(evt:Event):void
{
//initialize widget container instance (width,height,backgroundColor)
widget.initWidget(300,300,0xccffff);
}
]]>
</mx:Script>
</mx:Application>
4. Request an RSS Feed
Create a new function loadFeed and instantiate a new RSSLoader instance using the widget.newRSS() class factory. After creating the instance, add a listener to the Event.COMPLETE event and call rss.load(...)
private function loadFeed(feed:String):void
{
var rss:Object = widget.newRSS();
rss.addEventListener(Event.COMPLETE,onRSSLoaded);
rss.load(new URLRequest(feed));
}
In the onLoad event handler, make a call to loadFeed:
loadFeed("http://feeds.feedburner.com/yourminis");
5. Add the RSS Response Event
Once the RSS Feed is returned, the Event.COMPLETE Event is fired on the RSSLoader Instance.
Set the XML response to a variable that we will define.
private function onRSSLoaded(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
rssdata = XML( loader.data );
}
Add a bindable XML variable "rssdata" for display purposes.
[Bindable] private var rssdata:XML;
6. Add a repeater for displaying the contents of the feed
Create a panel and repeater and bind to our bindable "rssdata" variable.
<mx:Panel layout="vertical"
title="Flex RSS Widget"
width="{this.width-10}" height="{this.height-10}">
<mx:Repeater width="100%" height="100%"
id="items"
dataProvider="{rssdata.channel.item}">
<mx:VBox width="100%" horizontalAlign="left" creationCompleteEffect="Fade">
<mx:LinkButton
textAlign="left"
label="{ items.currentItem.title}"></mx:LinkButton>
<mx:TextArea paddingLeft="10" paddingRight="10" editable="false"
width="98%" cornerRadius="6" height="60"
backgroundColor="0xf9f9f9"
htmlText="{ items.currentItem.description}" ></mx:TextArea>
<mx:Text paddingRight="10"
width="98%"
textAlign="right"
text="{ (items.currentItem.creator==null?'':items.currentItem.creator)+
' ' + (items.currentItem.date==null?'':items.currentItem.date)}" />
</mx:VBox>
</mx:Repeater>
</mx:Panel>
The resulting code should look like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="300" height="300" initialize="onLoad()" backgroundAlpha="0">
<mx:Script>
<![CDATA[
public var widget:Object; //Widget
[Bindable]
private var rssdata:XML;
public function onLoad():void
{
addEventListener("widget-loaded",onWidgetLoaded);
}
public function onWidgetLoaded(evt:Event):void
{
//initialize widget container instance (width,height,backgroundColor)
widget.initWidget(300,300,0xccffff);
loadFeed("http://feeds.feedburner.com/yourminis");
}
private function loadFeed(feed:String):void {
var rss:Object=widget.newRSS();
rss.addEventListener(Event.COMPLETE,onRSSLoaded);
rss.load(new URLRequest(feed));
}
private function onRSSLoaded(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
rssdata = XML( loader.data );
}
]]>
</mx:Script>
<mx:Panel layout="vertical"
title="Flex RSS Widget"
width="{this.width-10}" height="{this.height-10}">
<mx:Repeater width="100%" height="100%"
id="items"
dataProvider="{rssdata.channel.item}">
<mx:VBox width="100%" horizontalAlign="left" creationCompleteEffect="Fade">
<mx:LinkButton
textAlign="left"
label="{ items.currentItem.title}"></mx:LinkButton>
<mx:TextArea paddingLeft="10" paddingRight="10" editable="false"
width="98%" cornerRadius="6" height="60"
backgroundColor="0xf9f9f9"
htmlText="{ items.currentItem.description}" ></mx:TextArea>
<mx:Text paddingRight="10"
width="98%"
textAlign="right"
text="{ (items.currentItem.creator==null?'':items.currentItem.creator)+
' ' + (items.currentItem.date==null?'':items.currentItem.date)}" />
</mx:VBox>
</mx:Repeater>
</mx:Panel>
</mx:Application>
7. Let's test it out before moving on:
Sign up for a yourminis account. If you already have an account, sign in now. You must be signed in before you can use the Online Widget Test Console.
Your widget should look like this:
8. Enable Resizing
By enabling resizing, users can customize the widget dimensions, along with the other settings, on the desktop or web sandbox before copying it to another destination or for personalization.
Add the Resize Event Handler:
private function onResize( evt:Event ):void
{
this.width = widget.width -10;
this.height = widget.height -10;
}
In the onLoad event handler, add a Listener for the widget.WIDGET_RESIZED event.
widget.addEventListener(widget.WIDGET_RESIZED,onResize);
Your widget should now be resizable in the Test Panel.
9. Add URL Click Tracking:
Add a click event handler and use the widget.navigateToURL(...) API:
private function onClick(url:String):void
{
widget.navigateToURL(new URLRequest(url));
}
Add a click event listener to the LinkButton element:
click="onClick( event.currentTarget.getRepeaterItem().link );"
Now, this widget will track all URL Clicks from this widget for future reporting. As well, if the widget is ever copied to someone's myspace page, the links, which are typically disabled on myspace, will now allow the user to click out to external URLs.
10. Add Dropdown Items
Every widget published to yourminis also offers the ability to customize options within a dropdown located on the top/right-hand corner of the widget.
Add a dropdown event handler function for the widget.DROPDOWN_LOADED Event:
function onDropDownLoaded( evt:Event):void
{
widget.chrome.addDropDownItem("yourminis","http://feeds.feedburner.com/yourminis",loadFeed);
widget.chrome.addDropDownItem("digg","http://digg.com/rss/index.xml",loadFeed);
widget.chrome.addDropDownItem("flickr","http://api.flickr.com/services/" +
"feeds/photos_public.gne?format=rss2",loadFeed);
}
Add an event Listener after the call to initWidget in the onLoad event handler:
widget.addEventListener(widget.DROPDOWN_LOADED,onDropDownLoaded);
11. Almost done... Get and Set user preferences.
User preferences will follow the widget whereever it is copied. As well, it will integrate with all the startpage and desktop environments so that the widget state can be saved across interactions.
Add a call to widget.setSetting in the loadFeed function:
function loadFeed(feed):void
{
widget.setSetting("feedurl",feed);
var rss = widget.newRSS();
rss.addEventListener(Event.COMPLETE,onRSSLoaded);
rss.load(new URLRequest(feed));
}
Now use widget.getSetting in the onLoad event when calling loadFeed:
loadFeed(widget.getSetting("feedurl","http://feeds.feedburner.com/yourminis"));
loadFeed(widget.getSetting("feedurl","http://feeds.feedburner.com/yourminis"));
The code should now look like this:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="300" height="300" initialize="onLoad()" backgroundAlpha="0">
<mx:Script>
<![CDATA[
public var widget:Object; //Widget
[Bindable]
private var rssdata:XML;
public function onLoad():void
{
addEventListener("widget-loaded",onWidgetLoaded);
}
public function onWidgetLoaded(evt:Event):void
{
//initialize widget container instance (width,height,backgroundColor)
widget.initWidget(300,300,0xccffff);
widget.addEventListener(widget.WIDGET_RESIZED,onResize);
widget.addEventListener(widget.DROPDOWN_LOADED,onDropDownLoaded);
loadFeed(widget.getSetting("feedurl","http://feeds.feedburner.com/yourminis"));
}
private function loadFeed(feed:String):void {
widget.setSetting("feedurl",feed);
var rss:Object=widget.newRSS();
rss.addEventListener(Event.COMPLETE,onRSSLoaded);
rss.load(new URLRequest(feed));
}
private function onRSSLoaded(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
rssdata = XML( loader.data );
}
private function onResize(evt:Event):void
{
this.width=widget.width-10;
this.height=widget.height-10;
}
private function onClick(url:String):void
{
widget.navigateToURL(new URLRequest(url));
}
private function onDropDownLoaded( evt:Event):void
{
widget.chrome.addDropDownItem("yourminis","http://feeds.feedburner.com/yourminis",loadFeed);
widget.chrome.addDropDownItem("digg","http://digg.com/rss/index.xml",loadFeed);
widget.chrome.addDropDownItem("flickr","http://api.flickr.com/services/" +
"feeds/photos_public.gne?format=rss2",loadFeed);
}
]]>
</mx:Script>
<mx:Panel layout="vertical"
title="Flex RSS Widget"
width="{this.width-10}" height="{this.height-10}">
<mx:Repeater width="100%" height="100%"
id="items"
dataProvider="{rssdata.channel.item}">
<mx:VBox width="100%" horizontalAlign="left" creationCompleteEffect="Fade">
<mx:LinkButton
textAlign="left"
label="{ items.currentItem.title}"
click="onClick( event.currentTarget.getRepeaterItem().link);"></mx:LinkButton>
<mx:TextArea paddingLeft="10" paddingRight="10" editable="false"
width="98%" cornerRadius="6" height="60"
backgroundColor="0xf9f9f9"
htmlText="{ items.currentItem.description}" ></mx:TextArea>
<mx:Text paddingRight="10"
width="98%"
textAlign="right"
text="{ (items.currentItem.creator==null?'':items.currentItem.creator)+
' ' + (items.currentItem.date==null?'':items.currentItem.date)}" />
</mx:VBox>
</mx:Repeater>
</mx:Panel>
</mx:Application>
12. Test!
Sign up for a yourminis account. If you already have an account, sign in now. You must be signed in before you can use the Online Widget Test Console.
Click on the dropdown in the top/right corner and click "flickr". Your widget should look like this:
Conclusion
Congratulations! You've created a fully functional RSS Flex Widget using the wAPI.
Next Steps
Go build some cool widgets!
