Check out the Latest Articles:
ActionScript 3.0 Basics part 4 – news reader component.

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.

News Reader Component

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 (219)

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" &amp;&amp; num &gt; 0) {
		 num--;
		 addNews();
	}else if (e.target.name == "bPrv" &amp;&amp; num &lt; 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 &lt; 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 &gt; 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 &amp;&amp; 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 (219) 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));
		}
	}
 
}



Kuba


Get my RSS-feedFallow me on Twitter


  1. [...] 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. [...]