This is a discussion on Leggere e visualizzare un RSS con Flash CS3 within the Articoli e tutorials forums, part of the Flash CS3 e Actionscript 3.0 category; Buongiorno a tutti.
Tempo fa, abbiamo visto come leggere un file XML caricato con Flash CS3.
Abbiamo anche visto come ...
Come RSS utilizzo quello di questo sito che potete vedere qui: Ultimi 10 Articoli
Dato che l' RSS mi mette a disposizione un nodo con attributo ' title ' che contiene il titolo dell' articolo e un nodo con attributo ' url ' che contiene l' indirizzo dell' articolo,
la nostra slide show avrà ogni titolo cliccabile linkato al corrispettivo articolo.
Vediamo come fare...
Creo un FLA, che salvo con nome ' rss.fla '. Al suo interno ho alcune grafiche ma la cosa che richiede un po di attenzione è un campo di testo dinamico cheho chiamato title_txt a cui assegnerò il valore del nodo
PHP Code:
<title>
figlio del nodo
PHP Code:
<head>
nell' XML generato dall' RSS.
Creo la Document class, un file AS che salvo con nome ' Rss.as ', implementata in questo modo:
Code:
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.net.URLRequest;
import flash.net.navigateToURL;
public class Rss extends MovieClip
{
private var xml:LoadingXML;
public var objects_array:Array;
private var clips_array:Array;
private var container_mc:MovieClip;
private var timer:Timer;
private var id:int=0;
public function Rss()
{
init();
}
private function init():void
{
stage.frameRate=31;
objects_array=new Array();
clips_array=new Array();
createContainer();
loadXML();
}
private function createContainer():void
{
container_mc=new MovieClip();
addChild(container_mc);
swapChildren(angles_mc,container_mc);
}
private function loadXML():void
{
xml=new LoadingXML(this);
}
public function createClipsAndFields():void
{
for(var i:int=0;i < objects_array.length;i++)
{
var clip:MovieClip=new MovieClip();
container_mc.addChild(clip);
clip.addChild(getTF(i));
clips_array.push(clip);
}
positionClips();
var time:TimerEvent;
go(time);
}
private function getTF(i:int):TextField
{
var field:TextField=new TextField();
field.autoSize=TextFieldAutoSize.LEFT;
field.multiline=false;
field.selectable=false;
field.embedFonts=true;
field.background=true;
field.backgroundColor=0xCB4425;
field.defaultTextFormat=getFormat();
field.text=objects_array[i].titolo;
return(field);
}
private function getFormat():TextFormat
{
var tf:TextFormat=new TextFormat();
tf.font='Hypatia Sans Pro Semibold';
tf.size=24;
tf.color=0xFFFFFF;
return(tf);
}
private function positionClips():void
{
for(var i:int=0;i < clips_array.length;i++)
{
clips_array[i].id=i;
clips_array[i].x=(stage.stageWidth-clips_array[i].width)/2;
clips_array[i].y=stage.stageHeight+clips_array[i].height;
clips_array[i].alpha=0;
clips_array[i].addEventListener(MouseEvent.MOUSE_DOWN,goURL);
}
}
private function startTimer():void
{
timer=new Timer(3000,1);
timer.addEventListener(TimerEvent.TIMER,go);
timer.start();
}
private function go(t:TimerEvent):void
{
clips_array[id].addEventListener(Event.ENTER_FRAME,fadeIn);
var i:int=id-1;
if(i < 0)
i=clips_array.length-1;
clips_array[i].addEventListener(Event.ENTER_FRAME,fadeOut);
}
private function fadeIn(e:Event):void
{
var arrA:Number=1;
var da:Number=arrA-e.currentTarget.alpha;
var aa:Number=da*.2;
e.currentTarget.alpha+=aa;
var arrY:Number=stage.stageHeight/2-e.currentTarget.height/2;
var dy:Number=arrY-e.currentTarget.y;
var ay:Number=dy*.2;
e.currentTarget.y+=ay;
if(Math.abs(dy)<=.2)
{
e.currentTarget.removeEventListener(Event.ENTER_FRAME,fadeIn);
e.currentTarget.y=arrY;
e.currentTarget.alpha=arrA;
id++;
if(id>=clips_array.length)
id=0;
startTimer();
}
}
private function fadeOut(e:Event):void
{
var arrA:Number=0;
var da:Number=arrA-e.currentTarget.alpha;
var aa:Number=da*.2;
e.currentTarget.alpha+=aa;
var arrX:Number=stage.stageWidth;
var dx:Number=arrX-e.currentTarget.x;
var ax:Number=dx*.2;
e.currentTarget.x+=ax;
if(Math.abs(dx)<=.2)
{
e.currentTarget.removeEventListener(Event.ENTER_FRAME,fadeOut);
e.currentTarget.x=(stage.stageWidth-e.currentTarget.width)/2;
e.currentTarget.y=stage.stageHeight+e.currentTarget.height;
e.currentTarget.alpha=arrA;
}
}
private function goURL(m:MouseEvent):void
{
var url:String=objects_array[m.currentTarget.id].link;
var request:URLRequest=new URLRequest(url);
navigateToURL(request);
}
}
}
Poi ho la mia classe LoadingXML, utilizzata più volte in questo sito che è strutturata come segue:
Code:
package
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.xml.*;
public class LoadingXML extends MovieClip
{
private var Root:MovieClip;
public function LoadingXML(m:MovieClip)
{
Root=m;
this.loadXML();
}
private function loadXML():void
{
var loader:URLLoader=new URLLoader();
loader.addEventListener(Event.COMPLETE,completeHandler);
var request:URLRequest=new URLRequest
('http://www.flepstudio.org/option,com_rss/feed,OPML/no_html,1.html');
try
{
loader.load(request);
}
catch(error:Error)
{
trace('Unable to load requested document.');
}
}
private function completeHandler(event:Event):void
{
var loader:URLLoader=URLLoader(event.target);
var result:XML=new XML(loader.data);
var myXML:XMLDocument=new XMLDocument();
myXML.ignoreWhite=true;
myXML.parseXML(result.toXMLString());
var node:XMLNode=myXML.firstChild;
Root.title_txt.text=node.firstChild.firstChild.firstChild.nodeValue;
var numeroArticoli:int=int(node.firstChild.nextSibling.childNodes.length);
for(var i:int=0;i < numeroArticoli;i++)
{
var obj:Object=new Object();
obj.titolo=node.firstChild.nextSibling.childNodes[i].attributes['title'];
obj.link=node.firstChild.nextSibling.childNodes[i].attributes['url'];
Root.objects_array.push(obj);
}
Root.createClipsAndFields();
}
}
}
Il risultato: ( cliccare un titolo per notare il giusto link preso dall' RSS )
Analizziamo il codice
Classe Rss.as
Proprietà
un' istanza della classe LoadingXML che caricherà , leggerà e immagazzinerà i dati del file XML
private var xml:LoadingXML;
un Array in cui immagazzino i dati dell' XML
public var objects_array:Array;
un Array in cui inseriscoogni MovieClip che creo inmodo da tenerne traccia e poterle recuperare a tempo debito
private var clips_array:Array;
una MovieClip chefunge da container di tutte le MovieClip che creo
private var container_mc:MovieClip;
un Timer
private var timer:Timer;
una variabile numerica che contiene un valore che incrementerò in modo da poter scorrere gli indici degli arrays
private var id:int=0;
Metodi
init();
imposto una velocità di frame rate
stage.frameRate=31;
inizializzo i due Arrays
objects_array=new Array();
clips_array=new Array();
chiamo il metodo createContainer
createContainer();
chiamo il metodo loadXML
loadXML();
createContainer();
creo la MovieClip contenitore
container_mc=new MovieClip();
la aggiungo al DisplayOnject o non sarebbe visibile
addChild(container_mc);
dico di scambiarsi di livello alle MovieClip container_mc e angles_mc che è una MovieClip con delle grafiche che ho in rss.fla
swapChildren(angles_mc,container_mc);
loadXML();
istanzio la classe LoadingXML passandogli il valore della root. LoadingXML, una volta eseguito tutto il codice chiamerà un metodo di Rss.as che si chiama createClipsAndFields
xml=new LoadingXML(this);
createClipsAndFields();
apro un ciclo con massima iterazione la lunghezza di objects_array ( che è stato popolato dalla classe LoadingXML )
for(var i:int=0;i < objects_array.length;i++)
{
creo una MovieClip
var clip:MovieClip=new MovieClip();
la aggiungo a container_mc
container_mc.addChild(clip);
aggiungo alla clip un campo di testo creato chiamando la funzione getTF che mi restituisce un campo di testo e gli passo ilvalore di i , l' iterazione del ciclo del momento
clip.addChild(getTF(i));
inserisco nell' array clips_array la clip
clips_array.push(clip);
}
chiamo il metodo positionClips
positionClips();
ora, potrei chiamare direttamente il metodo go(), ma per poterlo fare ( dato che il metodo go vuole un parametro di tipo TimerEvent, perchè è un metodo che sarà richiamato da un timer tranne appunto la prima volta ) ho bisogno di creare una sorta di istanza fantasma di TimerEvent
var time:TimerEvent;
ora posso chiamare il metodo go passandogli l'istanza TimerEvent
go(time);
getTF(i:int):TextField
creo un campo di testo dinamico assegnadogli le proprietà che mi occorrono
var field:TextField=new TextField();
field.autoSize=TextFieldAutoSize.LEFT;
field.multiline=false;
field.selectable=false;
field.embedFonts=true;
field.background=true;
field.backgroundColor=0xCB4425;
assegno un TextFormat al campo di testo chiamando il metodo getFormat che appunto mi restituisce una istanza di TextFormat
field.defaultTextFormat=getFormat();
assegno il testo al campo: il valore dell' indice i ( che mi è stato passato dall' interno del ciclo del metodo createClipsAndFields che abbiamo già visto ) dell' array objects_array che contiene delle istanze della classe Object che hanno una proprietà assegna in runtime dalla classe loadingXML al momento della lettura del file XML
field.text=objects_array[i].titolo;
restituisco il campo di testo
return(field);
getFormat():TextFormat
creo una istanza di TextFormat
var tf:TextFormat=new TextFormat();
gli assegno una font NB: per far si che la font sia visibile da tutti gli utenti e quindi inserita nell' SWF, leggi bene questo articolo: Incorporare fonts nell' SWF con Flash CS3
tf.font='Hypatia Sans Pro Semibold';
assegno una dimensione alla font
tf.size=24;
assegno un colore
tf.color=0xFFFFFF;
restituisco il TextFormat
return(tf);
positionsClips();
creo un ciclo con massima iterazione la lunghezza dell' array clips_array
for(var i:int=0;i < clips_array.length;i++)
assegno una proprietà alla MovieClip, dell'indice i nell' array clips_array, che chiamo id con valore pari a i ( iterazione del ciclo del momento )
clips_array[i].id=i;
posiziono le MovieClips
clips_array[i].x=(stage.stageWidth-clips_array[i].width)/2;
clips_array[i].y=stage.stageHeight+clips_array[i].height;
imposto alpha zero
clips_array[i].alpha=0;
aggiungo un listener in ascolto dell' evento MOUSE_DOWN sulla clip che chiamerà il metodo goURL
clips_array[i].addEventListener(MouseEvent.MOUSE_DOWN,goURL);
startTimer();
creo una istanza di Timer con valori: 3 secondi e una sola chiamata
timer=new Timer(3000,1);
faccio partire il timer che chiama la funzione go ( ecco spiegato il perchè dell' istanza fantasma di TimerEvent spiegato nel metodo init )
timer.addEventListener(TimerEvent.TIMER,go);
timer.start();
go();
creo un intervallo ENTER_FRAME alla clip dell' indice id ( variabile numerica spiegata all' inizio nelle proprietà )
clips_array[id].addEventListener(Event.ENTER_FRAME,fadeIn);
Adesso attenzione: dato che voglio che una data clip appare e poi quando apparirà la successiva deve scomparire, utilizzerò id-1 per recuperare la clip che deve sparire. Questo comporta però che id-1 potrebbe essere negativo quando id è zero, e sappiamo che nonesistono indici negativi di un array , quindi mi serve una logica condizionale che se id è zero ( id-1 ) dovrà essere non -1 ma l' ultima clip dell' array. Quindi creo una variabile numerica che controlla il valore di id e se id è zero , gli assegno un valore pari all' ultimo indice dell' array clips_array
var i:int=id-1;
if(i < 0)
i=clips_array.length-1;
infatti ecco che allo stesso momento creo un intervallo ENTER_FRAME sulla clip che deve sparire
clips_array[i].addEventListener(Event.ENTER_FRAME,fadeOut);
fadeIn();
Applico l'effetto inerzia sulla y e su alpha della clip
var arrA:Number=1;
var da:Number=arrA-e.currentTarget.alpha;
var aa:Number=da*.2;
e.currentTarget.alpha+=aa;
var arrY:Number=stage.stageHeight/2-e.currentTarget.height/2;
var dy:Number=arrY-e.currentTarget.y;
var ay:Number=dy*.2;
e.currentTarget.y+=ay;
if(Math.abs(dy)<=.2)
{
e.currentTarget.removeEventListener(Event.ENTER_FR AME,fadeIn);
e.currentTarget.y=arrY;
e.currentTarget.alpha=arrA;
arrivato a destinazione incremento la variabile id
id++;
controllo che non superi il numero massimo di indici dell' array clips_array
if(id>=clips_array.length)
se lo supera riporto id a zero
id=0;
richiamo la funzione startTimer
startTimer();
}
fadeOut();
Applico l'effetto inerzia sulla x e su alpha della clip
var arrA:Number=0;
var da:Number=arrA-e.currentTarget.alpha;
var aa:Number=da*.2;
e.currentTarget.alpha+=aa;
var arrX:Number=stage.stageWidth;
var dx:Number=arrX-e.currentTarget.x;
var ax:Number=dx*.2;
e.currentTarget.x+=ax;
if(Math.abs(dx)<=.2)
{
e.currentTarget.removeEventListener(Event.ENTER_FR AME,fadeOut);
e.currentTarget.x=(stage.stageWidth-e.currentTarget.width)/2;
e.currentTarget.y=stage.stageHeight+e.currentTarge t.height;
e.currentTarget.alpha=arrA;
}
goURL(m:MouseEvent);
creo una variabile di tipo stringa in cui inserisco il valore dell' indice ( con numero pari alla proprietà id aggiunta ad ogni clip ) della proprietà link dell' oggetto all' interno dell' Array
var url:String=objects_array[m.currentTarget.id].link;
istanzio la classe URLRequest
var request:URLRequest=new URLRequest(url);
e chiamo il browser
navigateToURL(request);
Riferimento: Leggere e visualizzare un RSS con Flash CS3
Ciao!
Scusa l'ignoranza, ma una volta creato un Reader in flash è possibile farlo lavorare in background?!
Intendo anche che non occupi perennemente lo spazio nella "barra delle applicazioni" ma nello startup tipo messanger o skype. E come quest'ultimi avvertono l'entrata di qualche amico, lo stesso faccia il reader con le news.
In caso sapresti indicarmi un articolo in merito o le librerie da guardare?!
Grazie!
Ciao,
credo che per fare quello che dici Flash non sia il software più adatto.
Tu parli di applicazioni desktop e a mio umile avviso credo che Java rimanga il miglior linguaggio per fare ciò.
Riferimento: Leggere e visualizzare un RSS con Flash CS3
immaginavo...
Speravo di riuscirci con flash dato che la gestione dell'interfaccia grafica con java non è molto libera e stimolante.
Ora vedrò se buttarmi su java o resistere con flash e inventarmi una visualizzazione alternativa... ogni idea è ben accetta!
cmq... grazie lo stesso, ciao!
scusami ma non riesco a seguire le tue spiegazioni.
Ho scaricato il file rss.as e loadingxml.
ma nel file fla cosa devo fare? ho creato un campo di testo dinamico senza assegnargli nulla. Nelle proprietà del progetto ho scritto di andarsi a prendere il file rss come componente. Ma poi?
leggo che fai delle operazioni di creazione di un movie clip ma...
potresti spiegarmi meglio passo passo quali sono i... passi? :D
tnx