Flash RSS Reader Pg.11
source: http://www.thegoldenmean.com
11 — Completing the Timeline Code
Timeline Code
Click frame 15 of the scripts layer. Make sure the Actions window is open. It’s time to pull all the pieces together into a real movie.
The absolute basics are easily stated:
- we import the ProcessRss class
- we create an instance of that class
- we supply a URL to the loadFeed() method.
The Minimum:
That’s really all that is required - the rest is refinement and window dressing. A menu of some sort would certainly be helpful if you plan to display more than one weblog syndication, and we will explore quite a few ways to modify the display of text in a TextArea component. (Please note that the colors specified are appropriate to my demo file, but you should feel free to substitute colors that better suit your site’s color scheme.)
You will recall from page Nine (in which we wrote the Class) that the ProcessRss constructor function is written to expect three arguments: the target movieclip, the target TextArea and the path to the proxy script. (Be especially sure to put your own specifications if you name your proxy file something other than rssProxy.php, or if you locate it somewhere other than the folder the HTML and swf files reside in.)
Class Instantiation and Preliminaries:
The timeline code accordingly begins this way:
//remove the movie preload message loadmsg_txt.removeTextField(); //bring in the parsing and ComboBox classes import ProcessRss; import mx.controls.ComboBox; //create instance of the parsing class var news:ProcessRss = new ProcessRss(this, output_ta, "rssProxy.php"); //declare the ComboBox instance so script can reference it var menu_cb:ComboBox;
We’re off and running! First we make the preloading message go away. Next the ProcessRss Class is imported as is the ComboBox Class (so that it can be referred to in code later without needing to type the cumbersome the fully qualified reference). Finally, an instance of ProcessRss is created and stored in the variable news. The three critical arguments are passed to the instance: the scope environment for the parsing Class is going the be the current movie, the output_ta TextArea will be used to display the text, and the name and path to the proxy script is made clear. Onward.
The Menu DataProvider:
The ComboBox is going to be populated by a dataProvider which is essentially an Array containing Objects with a strictly defined structure. We declare that Array now, and set it's first element to be the default value that will show when the movie loads initially.
//declare the Array that holds the menu elements //each element is an Object with 2 properties var feedList:Array = new Array(); //set the default menu item feedList.addItem({label:"Select A News Feed", data:null});
You can see already the form a dataProvider Array is required to have: every item in the feedList Array will be a generic Object, and every Object in the Array will have two properties: label and data. The value of the label property will be what shows in the ComboBox. The value of the data property will be the URL associated with that menu item. It would be insane to hand-write this Array. We have already built an XML document for this purpose. The next block of code is a function designed to extract the information from the feedList.xml document in your project folder and put it into the feedList Array.
I admit that the following function is a complex code block, but I chose to make this part of the movie self-contained in case you want to build some alternate menu system. For instance, if you want your menu to be a series of buttons, you can easily modify or eliminate this function that is geared toward a ComboBox component.
function buildMenu (menuURL:String):Void { var listXML:XML = new XML(); listXML.ignoreWhite = true; listXML.onLoad = function(success:Boolean):Void { if (success) { var rootNode:XMLNode = listXML.firstChild; var c:XMLNode = rootNode.firstChild; //travel the length of siblings while (c) { //add elements to Array feedList.addItem({label:c.childNodes[0].firstChild.nodeValue, data:c.childNodes[1].firstChild.nodeValue}); c = c.nextSibling; } } else { //error notification if XML fails to load output_ta.text = "<p>Menu file failed to load.</p>"; } } listXML.load(menuURL); }
There’s nothing fancy or out of the mainstream here. When invoked and passed the name of the XML document, the function uses our old friend the while loop to visit each child node, locate the text values of that node’s two children and create a new entry in the feedList Array in the form discussed previously. (By the way - if you are familiar with the methods of the Array Object you may be wondering about addItem(). No, this method is not a native Array Object method. It is a method which is added to the Array Object by Components that support dataProviders, one of which happens to be the ComboBox.)
//now call the function that populates the ComboBox buildMenu("feedList.xml"); //assign feedList as the data provider menu_cb.dataProvider = feedList; //assign the callback function to the ComboBox menu_cb.addEventListener("change", loadSelected);
The buildMenu() function is invoked and feedList.xml is passed to it as the file to parse. The feedList array is assigned to the ComboBox’s dataProvider property. The function that will be invoked when a new item is selected in the menu is assigned to “loadSelected()”. (Note that parentheses are not used in the addEventListener() method - we are assigning the function not invoking it.)
The ComboBox Callback:
What should happen when a user chooses an item from the ComboBox menu? We would like to have a new URL passed to the loadFeed() method. Recall that at the end of the previous code block we defined an event listener to the ComboBox and assigned a function named loadSelected(). Components broadcast notifications when events occur (for example when a change of state occurs). In this case the event we want to capture is “changed”. When a new item is selected by the user the ComboBox broadcasts its changed event and loadSelected() will “hear” that event and fire.
This type of function is called a callback function. Why not just assign
function loadSelected(obj:Object):Void { var linkAddress:String = obj.target.selectedItem.data; news.loadFeed(linkAddress); }
Style for the TextArea
The TextArea component has a number of properties that can be modified to customize its appearance. And, even more exciting, it supports a limited set of CSS selectors! (A helpful listing of supported CSS selectors may be read at visualintensity.com.) You must first create a new instance of the StyleSheet Object. You add styles to that Object using its setStyle() method, and then assign that Object as the styleSheet property of your Component. Don’t feel you need to be limited to the selectors and styles I used - make choices that suit your site. We might style the TextArea something like this:
var styles = new TextField.StyleSheet(); // define styles for TextArea component styles.setStyle("p", {fontFamily: 'Verdana,sans-serif', fontSize: '10px', marginLeft: '10px', color: '#333333'}); styles.setStyle("headline", {fontFamily: 'Georgia,serif', marginLeft: '2px', fontSize: '14px'}); styles.setStyle("a", {color: '#000066', fontWeight: 'bold', textDecoration: 'underline'}); // set the TextAreaInstance.styleSheet property to the newly //defined styleSheet object named styles output_ta.styleSheet=styles; output_ta.html=true; output_ta.embedFonts = false; output_ta.backgroundColor = 0xD8CCB6;
Now you understand why we invested the effort to place HTML tags in the output string when formatting the RSS data: they now enable us to gain control of the TextArea’s visual style. Too cool.
Style for the ComboBox
As with the TextArea, the ComboBox Component has a number of properties that can be modified to customize its appearance. The Flash documentation is a valuable resource to find what properties can be modified - I demonstrate just a few here. I especially love the alternatingRowColors property! Isn’t that awesome? Naturally you are encouraged to substitute colors that work with your site’s color scheme.
//define styles for the ComboBox component menu_cb.setStyle("themeColor", "haloOrange"); //you could experiement with the two //other themes: haloBlue and haloGreen menu_cb.setStyle("backgroundColor", 0xD8CCB6); menu_cb.setStyle("alternatingRowColors", [0xE9E1D6, 0xCEBEA6]); menu_cb.setStyle("fontFamily", "Verdana"); menu_cb.setStyle("fontSize", 10); menu_cb.setStyle("color", 0x333333); menu_cb.setStyle("embedFonts", false);
Tweaking the Tweening
Would you like to add some to add some bounce to your menu? One final note before leaving the ComboBox customizations is to point out that the opening and closing behavior can be modified by using the MX 2004 Tweening Class! This is much too big a can of worms for me to get into in this tutorial and anyway the topic has been covered in detail by others. If you are interested in pursuing this, you should read an article by Jen deHaan published on Macromedia’s DevNet site entitled Using the Tween and Transition Classes. It’s just another one of those little subtle things that aren’t strictly “necessary” but can make your project stand out as being somehow, well, “special” if you know what I mean!
Stop the Movie
All the code and visual assets have loaded now. We don’t want the timeline to keep looping, so conclude your movie with one last action:
stop();
This would be a good time to Publish your Flash movie, and upload the necessary assets to a web server for testing. If you want to keep everything in your project folder together on your website for organization there is no reason not to. However, the Classes (ProcessRss.as and all the XPath Classes) have now been compiled into the .swf file so they do not need to be on the server for this to work. What is required on the web server is a directory containing
- the HTML file Flash made when you Published the movie
- the .swf file Flash made when you Published the movie
- the rssProxy.php proxy script
- the feedList.xml file
Our final step in this tutorial is to rewrite the PHP proxy script we started on page Three, adding some additional security measures.
--top--