Article

Home » Client-side Coding » Flex Tutorials » Funky Flickr Flex Widgets

About the Author

Jack Herrington

Jack Herrington Jack Herrington is an engineer, author, and presenter who lives and works in San Francisco, USA. He writes regularly on the topics of Flex, Ajax, Silverlight, PHP, and Ruby on Rails at http://jackherrington.com.

View all articles by Jack Herrington...

Funky Flickr Flex Widgets

By Jack Herrington

April 16th, 2009

Reader Rating: 10

Page: 1 2 3 Next

A web widget, or badge, is a small, embeddable element that you can add to your site that will display your content from another web service. But enabling web widgets to work properly can be a hassle. One of the easiest ways to build a widget is to build a Flex application that compiles a Flash object.

In this article, I’ll show you how to create a small Flex widget that we’ll call FlickrTag. The widget can be embedded on any web page and will show a set of Flickr photos matching a specified search term, centered on a particular location; for example, you could use the widget to show dog pictures near Fremont, California. You can use the code as a basis for your own widgets, as well—the principles are the same whether you use Flickr or some other service.

There's a lot to do, so let’s dig right in. The first step is to install Flex Builder 3, which is a development environment for Flex. You can download the Flex SDK, which is free, and build this code from the command line. But trust me, it’s easier to just use Flex Builder 3, and there is a 60-day free trial of it from Adobe. You’ll also need a Flickr API key so that your widget can retrieve images.

Showing Some Photos

With Flex Builder installed, let’s create a new Flex Builder project and have a look at the first version of our FlickrTag widget. This first version will retrieve a list of photos from Flickr using a REST request and arrange them as a wide strip of images. In the versions that follow, we’ll have some pop-up functionality that shows more information about the photos.

Here is all the MXML code we need. You can view a complete listing in flickrmap1.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
   layout="absolute" creationComplete="onStartup()"  
   width="660" height="100"
   horizontalScrollPolicy="off" verticalScrollPolicy="off">

<mx:Script>
<![CDATA[

// … We'll fill this in soon

]]>
</mx:Script>

<mx:HTTPService id="flickrSearch" resultFormat="e4x"  
   result="onFlickrResult(event)" />

<mx:HBox id="hbPictures" cornerRadius="15" width="660" height="100"  
   borderColor="#00FF00" borderThickness="3" borderStyle="solid"  
   backgroundColor="#CCFFCC" paddingBottom="10" paddingTop="10"
   paddingLeft="10" paddingRight="10" horizontalGap="5"
   horizontalScrollPolicy="off" verticalScrollPolicy="off">
</mx:HBox>

</mx:Application>

At the top of the file we have the <mx:Application> tag that wraps the whole Flex application. This tag stipulates that when the application is loaded we should call the onStartup method. This method can be found within the <mx:Script> tags, where we also import some required classes and set some variables to store image data and a constant to store the Flickr API key:

<mx:Script>
<![CDATA[
import mx.core.UIComponent;
import mx.controls.Image;
import mx.rpc.events.ResultEvent;

private const FLICKR_KEY:String = 'Your Flickr API Key';

private var images:Array = [];
private var imageItems:Array = [];

private function onStartup() : void {
 flickrSearch.url = createFlickrURL();
 flickrSearch.send();
 for( var imgItem:int = 0; imgItem < ( hbPictures.width - 30 ) / 80; imgItem++ ) {
   var newImage:Image = new Image();
   newImage.data = null;
   newImage.width = 75;
   newImage.height = 75;
   imageItems.push( newImage );
   hbPictures.addChild( newImage );
 }
}

This onStartup method uses the createFlickrUrl method to set the URL for the Flickr search query:

private function createFlickrURL( ) : String {
 var query:String = 'http://api.flickr.com/services/rest/?api_key='+
     FLICKR_KEY;  
 query += '&method=flickr.photos.search&extras=geo';
 query += '&text='+parameters.text;
 query += '&lat='+parameters.lat;
 query += '&lon='+parameters.lon;
 query += '&radius=30';
 query += '&per_page=100&page=1&sort=date-posted-desc';
 return query;
}

The createFlickrUrl function uses some parameters that are specified in the widget creation code. We’ll see how to specify those in a second.

To finish up with this code we look at the onFlickrResult method, which is called when Flickr sends back an XML response:

private function onFlickrResult( event:ResultEvent ) : void {
 for each( var photo:XML in event.result..photo ) {
   var smallPhotoUrl:String = 'http://static.flickr.com/'+photo.@server+
       '/'+photo.@id+'_'+photo.@secret+'_s.jpg';
   var bigPhotoUrl:String = 'http://static.flickr.com/'+photo.@server+
       '/'+photo.@id+'_'+photo.@secret+'.jpg';
   images.push( {  
     source:smallPhotoUrl,
     bigSource:bigPhotoUrl,
     title:photo.@title,
       latitude:photo.@latitude,
       longitude:photo.@longitude
     } );
 }
 setPictures();
}

The onFlickrResult method looks for all of the photo tags and stores the picture location, the title, and the latitude and longitude in an object within the images array.

Once the onFlickResult method has chewed through all of the photos, the setPictures method compiles a random sampling of the Flickr images returned from the feed and puts them in a box, hbPictures:

private function setPictures() : void {
 for each( var ii:Image in imageItems ) {
   var imgIndex:int = int( Math.random() * images.length );
   ii.data = images[ imgIndex ];
   ii.source = images[ imgIndex ].source;
 }
}  
]]>
</mx:Script>

So, where do the search term, the latitude, and the longitude come from? Well, they come from the source URL we specify to include the Flash file. Our HTML template uses JavaScript to embed the element, so we’ll need to tweak the JavaScript in the index.template.html file managed by Flex Builder 3, found in the html-template folder within your project folder. You can edit the index.html.template file by double-clicking the file or right clicking on the file in the Project panel and selecting Open.

You can see the updated code for the template below:

} else if (hasRequestedVersion) {
 AC_FL_RunContent(
   "src", "${swf}?text=dog&lat=37.57228&lon=-122.0747",
   "width", "${width}",
   "height", "${height}",
   "align", "middle",
   "id", "${application}",
   "quality", "high",
   "bgcolor", "${bgcolor}",
   "name", "${application}",
   "allowScriptAccess","sameDomain",
   "type", "application/x-shockwave-flash",
   "pluginspage", "http://www.adobe.com/go/getflashplayer"
 );
}

We’ve altered the value of the src parameter. In this case, I’m specifying that the text we should look for is dog, and that the latitude and longitude indicates the location of Fremont. When we launch this from Flex Builder 3, we should see a strip of images, as depicted below.

Our first version of FlickrTag

The biggest problem with this widget is the size of the download. Have a look for the FlickrTag.swf file that is sitting in the project output folder; this is a folder inside your project folder called bin-debug by default. Even with this limited functionality, the widget clocks in at around 400KB, which is more of a whoa-didget than a widget.

To trim it down to size, we’ll use a new feature of Flash 9 called a runtime shared library (RSL). This means that we’ll split our code, which is small, from the Flex Framework code, which is fairly fat. The first time our visitor visits, they will download both our code and the Flex Framework code; after that, they’ll just download our code and use the Framework version, which is cached in the player.
Thankfully, moving to RSLs is super easy. The first step is to go into the project's Properties panel under the Project menu, and select Flex Build Path. You'll see this dialog, shown below.

The Project Settings dialog showing the Flex Build Path settings

From here we select the Flex Build Path tab, and within that select the Library path tab. Once we’re there we expand the framework.swc file, which is the big Flex Framework library. Click on the Link Type item and then click on the Edit button.
That brings up the Library Path Item Options dialog, shown below.

The Library Path Item Options dialog

This is the dialog where we make the change from merging the framework.swc code into our Flash application, or linking it as an RSL. We want to uncheck the Use same linkage as framework checkbox, then select Runtime Shared Library, as shown above.

With that done we can launch the widget, and have another look at the size of the widget’s SWF file and see that it’s been significantly reduced. And it really should stay around that size as we add more functionality to it.

Flex, combined with the use of RSLs, is the way to build Flash widgets quickly.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article