Home >
In my last "Flex 101" post, we reviewed the basics of consuming data through a web service. This time around, we are going to review the basics of loading a simple RSS XML feed and displaying the results in a Flex List component.
The example below shows what we'll be building in this post. It is a straight-forward application that consumes an RSS feed from Adobe Feeds, and displays the results in a Flex List component. If you single-click on an item in the list, the row in the list will expand and show the RSS item's description. If you double-click on an item, it will open up the RSS item's link url in a new window. Take it for a test drive, and then we'll get into how it works...
You can see that the application is fairly simple... It is basically just a list that contains data, with some mouse actions applied to. Let's examine the main application file first. You can see the code for the main application file below.
main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="httpService.send()"
backgroundColor="#CCCCCC"
themeColor="#999999" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import flash.net.navigateToURL;
import mx.events.ListEvent;
import mx.controls.Alert;
import mx.utils.ObjectUtil;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
use namespace rdf;
namespace purl = "http://purl.org/rss/1.0/";
use namespace purl;
namespace dc = "http://purl.org/dc/elements/1.1/";
use namespace dc;
[Bindable]
private var loading : Boolean = true;
private function onResult( event : ResultEvent ) : void
{
list.dataProvider = XML( event.result )..item;
loading = false;
}
private function onFault( event : FaultEvent ) : void
{
Alert.show( ObjectUtil.toString( event.fault ), "Service Error" );
loading = false;
}
private function onItemDoubleClick( event : ListEvent ) : void
{
var url : String = event.itemRenderer.data.link.toString()
navigateToURL( new URLRequest( url ), "_blank" );
}
]]>
</mx:Script>
<mx:HTTPService
id="httpService"
url="http://feeds.adobe.com/xml/rss.cfm?query=byMostRecent"
resultFormat="e4x"
result="onResult( event )" />
<mx:ApplicationControlBar dock="true">
<mx:Text
width="100%"
text="Select an item to see the description. Double-click to open the url in a new window."
selectable="false" />
</mx:ApplicationControlBar>
<mx:List
width="100%"
height="100%"
id="list"
variableRowHeight="true"
itemRenderer="ListItemRenderer"
doubleClickEnabled="true"
itemDoubleClick="onItemDoubleClick(event)" />
<mx:ProgressBar
visible="{ loading }"
includeInLayout="{ loading }"
indeterminate="true"
horizontalCenter="0"
verticalCenter="0"
labelPlacement="center" />
</mx:Application>
The main.mxml file contains a HTTPService that is used to load the RSS feed, a List to display the data, a ProgressBar to show an animation while the RSS feed is loading, and a simple ApplicationControlBar to show instructions how to interact with it. When the application loads, the httpService.send() method is invoked on the "creationComplete" event. This tells the HTTPService to request data from the HTTPService's url property. When this result is returned to the client, it is handled by the onResult function. In the onResult function, the list's dataprovider is set, and the loading Boolean value is set to false. When the loading property is set, it hides the progess bar instance using Flex's data bindings on the visible and includeInLayout properties. When a user double-clicks on an item in the list, the onItemDoubleClick() function is invoked, which opens the item's URL in a new window.
One very important thing to note in this example is the usage of namespaces. The three namespaces that are defined in this code segment allow the values of the RSS feed to be accessed within your application. These namespaces match those that are in the RSS feed itself. Without these namespaces, you would not be able to acces the nodes of the XML document.
Now, let's examine the item renderer that is used to show the content of the RSS feed:
ListItemRenderer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox
xmlns:mx="http://www.adobe.com/2006/mxml"
verticalGap="0"
horizontalScrollPolicy="off"
verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
import flash.utils.setTimeout;
import mx.controls.List;
namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
use namespace rdf;
namespace purl = "http://purl.org/rss/1.0/";
use namespace purl;
namespace dc = "http://purl.org/dc/elements/1.1/";
use namespace dc;
[Bindable]
private var list : List;
override public function set data(value:Object):void
{
super.data = value;
list = owner as List;
}
]]>
</mx:Script>
<mx:Label
width="100%"
fontWeight="bold"
fontSize="14"
text="{ data.title }"
selectable="false" />
<mx:Label
width="100%"
text="subject: { data.subject }"
selectable="false" />
<mx:Label
width="100%"
text="author: { data.creator }"
selectable="false" />
<mx:Text
color="#333333"
id="description"
htmlText="{ data.description }"
width="{ width }"
visible="{ list.selectedItem == data }"
includeInLayout="{ list.selectedItem == data }"
selectable="false" />
</mx:VBox>
The item renderer used to display the RSS item's information is also very basic. It consists of a VBox, which will vertically stack it's child components. Inside, it contains three Label components, and a Text component. The labels are used to display the title, categories, and author for each entry in the RSS item using standard data bindings. The text component is used to display the item's description. The Text component is used in this instance because it will automatically wrap the description text; labels are used in the other instances because I did not want the text to wrap to the next line.
The visible and includeInLayout properties on the description text instance control whether or not you can see the description. You'll notice that these are bound to the selectedItem of the list variable. The list variable contains a reference to the parent list component, which gets identified by the owner property within the overridden set data function. Whenever the list's selectedItem property equals the data of the current renderer, the item's description will be displayed, which resizes the renderer to show the full description.
And that's it. This is all you need to consume and display a RSS feed within your own application! It can get much more sophisticated than this, but it doesn't always need to be that complicated.
Related Links:
Adobe Feeds
Adobe Feeds RSS Generator
___________________________________
Andrew Trice
Principal Architect
Cynergy Systems
http://www.cynergysystems.com




Facebook Application Development
Looks very nice..
Nice little example. Looks cool
The RSS feed I'm using has a namespaced thumbnail, like this:
I've added the yahoo namespace up with all the rest in the main.xml and ListItemRenderer, so that's working, but when I add the mx:Image control and try to display the image, I get nothing. Any guess what I'm doing wrong? This is how I've added it:
id="thumbnail"
source="{ data.thumbnail.@url }"
width="{ width }" />
Is this a crossdomain issue? I'm just trying to run the thing on my local box in Flex.
I can't see your XML markup b/c its in HTML format, so it isn't rendererd in the page. Can you paste it replacing the angle brackets with some other character?
Thanks for trying to help. Here's a screenshot:
http://www.screencast.com/t/rPWnkDDoVL
Is there an easier way to reference the List item from the ItemRenderer? It seems somewhat kludgey to set it in this manner.
You could try binding directly to owner.selectedItem, but I think it gives you compiler warnings about owner not being bindable.
Can you give more info on declaring namespaces? For example, I have
### result xmlns="http://www.inktomi.com/"
in my RSS feed, and
### namespace ink = "http://www.inktomi.com/";
### use namespace ink;
below the imports in my flex app. I made up the ink... Should I not see the xmls="" reference within the debugger?