We already know how to load xml data, use event listeners and tweener ( if you are not fallowing along I recomend to read the previous tutorials: part 1, part 2 , part 3). Now it’s time to combine this knowlage in one project. We will make simple animated news reader that will display the title, date and description of our news. The data for this component will be loaded from xml file, we will also learn how to use html tags in Flash text fields.
We have fallowing xml structure:
<?xml version="1.0" encoding="utf-8"?> <data> <news date="06-04-2009"> <title> <![CDATA[Lorem ipsum dolor sit amet. ]]> </title> <message> <![CDATA[Vestibulum placerat,<font color='#FF6600'> turpis vitae mollis placerat</font>, nunc arcu ornare leo, at lacinia sapien metus a augue. Etiam pretium, eros ac laoreet ultrices, tellus lectus cursus tortor.]]> </message> </news> <news date="05-04-2009"> <title> <![CDATA[Curabitur lectus. Phasellus et lectus. ]]> </title> <message> <![CDATA[. Proin diam. Ut mattis pulvinar ligula. Vestibulum vitae sem ut nulla porttitor pharetra. Cras ipsum tortor, posuere at, imperdiet sit amet, scelerisque id, turpis. ]]> </message> </news> </data>
I think this structure is preaty clear, we have the data tag which wraps the whole xml data then we have the news tag which represtent our news and consist one atribute (date) and two elements title and message. We are placing our text in the < ![CDATA[]] > tag because othervise if we want to use the html tags in our text, flash will through an error that xml is not properly parsed. If you want to learn more about the < ![CDATA[]] > tag read this article. Here is the list of html tags supported by Flash. We want to use the dynamic text field with font embed. Font embed means that any user that enters your website will see the same font, when you doesnt embed the font it’s swiched to default when user doesn’t have it. The disadventage of embeded text field is that you cant use two font styles in one text field for example bold and regular or italic. When you embed the font Flash is told to use only specyfied font style, event the html tags wont work. In embeded text field you can use the font color html tag or the font size but you cannot make font italic and reagular in the same field. There are some great articles about embeding the fonts in flash, check them out!
So we have the data source for our news reader, now it’s time to load this data from xml into Flash.
package { import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; import flash.display.Sprite; public class Actions extends Sprite { private var xml:XML; // our xml file public function Actions(){ readXML(); } private function readXML():void { var loader:URLLoader = new URLLoader(new URLRequest("news.xml")); loader.addEventListener(Event.COMPLETE, xmlLoaded); } private function xmlLoaded(e:Event):void { xml = new XML(e.target.data); } } }
I have called my document class Actions, in the constructor we are calling the readXML function. This function in creating the loader variable which loads our xml, we have also added event listener that listens for the complete event. When loading is completed the xmlLoaded function is called and data is assigned to our variable.
We have already loaded our xml data, now we need some user interface and container for our news. I have placed two buttons on the stage, I gave them an instance names of bPrv and bNext. Those button will be used to switch between the news.
I also have a MovieClip in my Library called SingleNews, it’s exported to ActionScript with the same name and it contains three embeded dynamic text fields with fallowing instance names: title, date and news. Don’t place the SingleNews MovieClip on the stage! If you want to use my files download them here: source (243)
Now it’s time to add some events for our buttons.
private function xmlLoaded(e:Event):void { xml = new XML(e.target.data); bNext.buttonMode = true; bPrv.buttonMode = true; bNext.mouseChildren = false; bPrv.mouseChildren = false; bNext.addEventListener(MouseEvent.ROLL_OVER, bOver); bNext.addEventListener(MouseEvent.ROLL_OUT, bOut); bPrv.addEventListener(MouseEvent.ROLL_OVER, bOver); bPrv.addEventListener(MouseEvent.ROLL_OUT, bOut); bNext.addEventListener(MouseEvent.CLICK, bClick); bPrv.addEventListener(MouseEvent.CLICK, bClick); addNews(); }
I have added some code to our xmlLoaded function, first we set the buttonMode to true because we want the hand cursor to be shown over our buttons, then we set the mouseChildren property to false because we dont want the children of our button to react on the cursor. Finally we are adding the roll out, roll over and click events.
private function bOver(e:MouseEvent):void { Tweener.addTween(e.target, {alpha:0.75, time:1, transition:"easeOutExpo" } ); } private function bOut(e:MouseEvent):void { Tweener.addTween(e.target, {alpha:1, time:1, transition:"easeOutExpo" } ); }
Here we specified the bOver and bOut functions, we are using tweener for the animation, roll over will darken our button. Now we will add the click event function, before the constructor we will specify two variables num and curNum booth integer. Num specifies the index of news that will be open and the curNum will specifie the index of currently open news. Out bClick function will look like this:
private function bClick(e:MouseEvent):void { if (e.target.name == "bNext" && num > 0) { num--; addNews(); }else if (e.target.name == "bPrv" && num < xml.news.length()-1 ){ num++; addNews(); } }
So what are we doing in the bClick function, first we check which button was clicked if it’s a next button and the num value is greater the 0 then we decrement the num because the newest message is number 0, then we call addNews function (we will define it in a minute). Otherwise if the button clicked is the Preview button and our num is less then the length of all news we are incrementing the num and the calling the addNews function.
Now it’s time to define our addNews function, it’s the most important function of our little application I will explain how it works by commenting the code:
private function addNews():void { // first we create our SingleNews object; var sn:SingleNews = new SingleNews(); // we give it a name of "sn" + number of the news sn.name = "sn" + num; // we set the x position sn.x = -(sn.width); // we set the y value that will always be centered sn.y = Math.round(stage.stageHeight / 2); /*/then we read the xml and assign the title to our text field, we use the 'htmlText' instead of 'text' because we want html tags to be read correctly/*/ sn.title.htmlText = String(xml.news[num].title); /*/we are not using html tags for the date so we don't need to use the 'htmlText'/*/ sn.date.text = String(xml.news[num].@date); // we are inserting the message sn.news.htmlText = String(xml.news[num].message); /*/ we dont want the children of our news to respond mouse events so we set the mouseChidren = false/*/ sn.mouseChildren = false; // we add our news to the stage addChild(sn); /*/so now we want to check if the number of news that we will be displaying is less or greater the the number of news that we are already displaying we need this for the animation, the news will fly from the left or from the right side of the screen. There is also a third option when the news is the first news to be displayed./*/ if (curNum < num) { /*/ if we choose to see the previous news we will tween our old news from the center to the right side of the screen on complete we will remove out news because we dont want to store all the news in the memory, so we will call the removeSingleNews function and pass to it the curNum /*/ Tweener.addTween(this.getChildByName("sn" + curNum), { x:stage.stageWidth + this.getChildByName("sn" + curNum).width / 2, time:1, transition:"easeOutExpo", onComplete:removeSingleNews, onCompleteParams:[curNum] } ); /*/we will place our new news at the left side of the screen /*/ this.getChildByName("sn" + num).x = -(this.getChildByName("sn" + num).width); /*/finaly we will tween it to the center/*/ Tweener.addTween(this.getChildByName("sn" + num), { x:stage.stageWidth / 2, time:1, transition:"easeOutExpo" } ); } else if (curNum > num) { /*/here we choose to see the next news so we do the opposite, first we tween the old news to the side the we place the new message on the right side of the screen and finally we tween it to the center of the screen/*/ Tweener.addTween(this.getChildByName("sn" + curNum), { x: -this.getChildByName("sn" + curNum).width / 2, time:1, transition:"easeOutExpo", onComplete:removeSingleNews, onCompleteParams:[curNum] } ); this.getChildByName("sn" + num).x = stage.stageWidth +(this.getChildByName("sn" + num).width / 2); Tweener.addTween(this.getChildByName("sn" + num), { x:stage.stageWidth / 2, time:1, transition:"easeOutExpo" } ); } else if( curNum == 0 && num == 0){ /*/if our news is the first news we just want to tween it to the center of the screen/*/ Tweener.addTween(this.getChildByName("sn0"), { x:stage.stageWidth / 2, time:1, transition:"easeOutExpo" } ); } // at the end we set the curnNum = num; curNum = num; } private function removeSingleNews(i:int):void { /*/this function removes the old function from the screen/*/ this.removeChild(getChildByName("sn" + i)); }
This is it, now we have completed our News reader component. You can download the source here: source (243) Below I also post the whole code in one package :)
package { import flash.events.Event; import flash.events.MouseEvent; import flash.net.URLLoader; import flash.net.URLRequest; import flash.display.Sprite; import caurina.transitions.*; public class Actions extends Sprite { private var xml:XML; // our xml file private var num:int = 0; // the number of our news that will be open private var curNum:int = 0; // number of our curently displayed news public function Actions(){ // we call the function to load xml readXML(); } private function readXML():void { // we load the xml var loader:URLLoader = new URLLoader(new URLRequest("news.xml")); loader.addEventListener(Event.COMPLETE, xmlLoaded); } private function xmlLoaded(e:Event):void { /*/ when xml is loaded we assign the data to our xml object/*/ xml = new XML(e.target.data); /*/we set the Preview/Next button eventes/properties/*/ bNext.buttonMode = true; bPrv.buttonMode = true; bNext.mouseChildren = false; bPrv.mouseChildren = false; bNext.addEventListener(MouseEvent.ROLL_OVER, bOver, false, 0, true); bNext.addEventListener(MouseEvent.ROLL_OUT, bOut, false, 0, true); bPrv.addEventListener(MouseEvent.ROLL_OVER, bOver, false, 0, true); bPrv.addEventListener(MouseEvent.ROLL_OUT, bOut, false, 0, true); bNext.addEventListener(MouseEvent.CLICK, bClick, false, 0, true); bPrv.addEventListener(MouseEvent.CLICK, bClick, false, 0, true); // the we add the first news addNews(); } private function bOver(e:MouseEvent):void { // roll over animaction Tweener.addTween(e.target, {alpha:0.75, time:1, transition:"easeOutExpo" } ); } private function bOut(e:MouseEvent):void { // roll out animation Tweener.addTween(e.target, {alpha:1, time:1, transition:"easeOutExpo" } ); } private function bClick(e:MouseEvent):void { /*/this is out click handler, first it checks which button was clicked then it increments or decrements the num and finaly it calls the addNews function/*/ if (e.target.name == "bNext" && num > 0) { num--; addNews(); }else if (e.target.name == "bPrv" && num < xml.news.length()-1 ){ num++; addNews(); } } private function addNews():void { // first we create our SingleNews object; var sn:SingleNews = new SingleNews(); // we give it a name of "sn" + number of the news sn.name = "sn" + num; // we set the x position sn.x = -(sn.width); // we set the y value that will always be centered sn.y = Math.round(stage.stageHeight / 2); /*/then we read the xml and assign the title to our text field, we use the 'htmlText' insted of 'text' because we want html tags to be read corectly/*/ sn.title.htmlText = String(xml.news[num].title); /*/we are not using html tags for the date so we don't need to use the 'htmlText'/*/ sn.date.text = String(xml.news[num].@date); // we are inserting the message sn.news.htmlText = String(xml.news[num].message); /*/ we dont want the children of our news to respond mouse events so we set the mouseChidren = false/*/ sn.mouseChildren = false; // we add our news to the stage addChild(sn); /*/so now we want to check if the numer of news that we will be displaying is less or greater the the number of news that we are already displaying we need this for the animation, the news will fly from the left or from the right side of the screen. There is also a third option when the news is the first news to be displayed./*/ if (curNum < num) { /*/ if we choose to see the previous news we will tween our old news from the center to the right side of the screen on complete we will remove out news because we dont want to store all the news in the memory, so we will call the removeSingleNews function and pass to it the curNum /*/ Tweener.addTween(this.getChildByName("sn" + curNum), { x:stage.stageWidth + this.getChildByName("sn" + curNum).width / 2, time:1, transition:"easeOutExpo", onComplete:removeSingleNews, onCompleteParams:[curNum] } ); /*/we will place our new news at the left side of the screen /*/ this.getChildByName("sn" + num).x = -(this.getChildByName("sn" + num).width); /*/finaly we will tween it to the center/*/ Tweener.addTween(this.getChildByName("sn" + num), { x:stage.stageWidth / 2, time:1, transition:"easeOutExpo" } ); } else if (curNum > num) { /*/here we choose to see the next news so we do the aposite, first we tween the old news to the side the we place the new message on the right side of the screen and finaly we tween it to the center of the screen/*/ Tweener.addTween(this.getChildByName("sn" + curNum), { x: -this.getChildByName("sn" + curNum).width / 2, time:1, transition:"easeOutExpo", onComplete:removeSingleNews, onCompleteParams:[curNum] } ); this.getChildByName("sn" + num).x = stage.stageWidth +(this.getChildByName("sn" + num).width / 2); Tweener.addTween(this.getChildByName("sn" + num), { x:stage.stageWidth / 2, time:1, transition:"easeOutExpo" } ); } else if( curNum == 0 && num == 0){ /*/if our news is the first news we just want to tween it to the center of the screen/*/ Tweener.addTween(this.getChildByName("sn0"), { x:stage.stageWidth / 2, time:1, transition:"easeOutExpo" } ); } // at the end we set the curnNum = num; curNum = num; } private function removeSingleNews(i:int):void { /*/this function removes the old function from the screen/*/ this.removeChild(getChildByName("sn" + i)); } } }








[...] ActionScript 3.0 Basics part 1. ActionScript 3.0 Basics part 2. ? Simple Menu, using tweener Tutorial. ActionScript 3.0 Basics part 3 -loading xml data. ActionScript 3.0 Basics part 4 ? news reader component. [...]