En este tutorial voy a explicar los principios básicos a seguir para la creación de un
. Para lograr esto vamos a crear un componente que cotenga un rectangulo que se mueva. Cada vez que este componente sea agregado a una aplicacion flex, entonces la aplciación tendrá un cuadrado que se mueva hacia la derecha. Por mas inutil que resulte este componente, me parece perfecto ejemplo didáctico. De todas maneras próximamente prometo crear componentes mas utiles y explicar como los hice.
Para empezar el tutorial debemos entender los conceptos básicos que estan presentes en todos los componentes flex, es decir, en todas las clases de flex que heredan de la clase
(que es el componente mas básico).
package com.view
{
import flash.events.TimerEvent;
import flash.utils.Timer;
import mx.core.UIComponent;
import mx.skins.ProgrammaticSkin;
public class MyFirstComponent extends UIComponent
{
/*
Defino las variables que voy a utilizar en este componente.
*/
private var bloque : ProgrammaticSkin;
private var _timer : Timer = new Timer(50);
private var procesarBloque : Boolean = false;
public function MyFirstComponent()
{
super();
trace("constructor");
/*
Empiezo el timer y defino un handler llamado pintar para el evento
TimerEvent.TIMER que es disparado por el timer cada 50 miliseg.
*/
_timer.addEventListener(TimerEvent.TIMER,pintar);
_timer.start();
}
override protected function createChildren() : void
{
super.createChildren();
/*
Creo un ProgrammaticSkin y lo agrego a la lista de hijos del
componente.
*/
bloque = new ProgrammaticSkin();
this.addChild(bloque);
trace("createChildren");
}
/*
Utilizamos este metodo para cambiar el tamaño de nuestro componente
*/
override protected function measure() : void
{
super.measure();
trace("measure");
measuredWidth += 30;
measuredHeight += 30;
}
override protected function commitProperties() : void
{
super.commitProperties();
trace("commitProperties");
/*
Debemos asegurarnos de que "bloque" este creado.
*/
if(bloque)
{
//Solo queremos aumentar la coordenada x de "bloque" si es menor a 100.
if(bloque.x<100) procesarBloque = true;
else procesarBloque = false;
/*
Esta condicional nos permite restringir los bloques que deseamos que sean procesados
esto se puede usar para mejorar el rendimiento del componente ya que de esta manera
podemos controlar la ejecucion de las porciones de codigo, no se debe ejecutar la
porcion que no sea necesaria.
*/
if(procesarBloque)
{
bloque.x++;
}
}
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
trace("updateDisplayList");
/*
En este punto pintamos nuestro bloque con el el ancho y alto de 200.
es importante dear de pintar a "bloque si no han ocurrido modificaciones de sus propiedads,
para eso usamos la bandera "procesarBloque" que tambien la utilizamos en el commmitproperties
*/
if(procesarBloque)
{
//bloque.graphics.clear();
bloque.graphics.lineStyle(1,0x000000,1);
bloque.graphics.beginFill(Math.random() * 20000000, 1);
bloque.graphics.moveTo(unscaledWidth,unscaledHeight);
bloque.graphics.lineTo(unscaledWidth,0);
bloque.graphics.lineTo(0,0);
bloque.graphics.lineTo(0,unscaledHeight);
}
}
/*
Esta funcion se llama cada 50 milisegundos.
*/
public function pintar(e : TimerEvent) : void
{
//Le digo a flex que cuando considere pertinente puede hacer
//un llamado a la funcion "commitProperties".
this.invalidateProperties();
this.invalidateDisplayList();
this.invalidateSize();
}
}
}
Las variable bloque será donde pintaremos todo nuestro cuadrado, un ProgrammaticSkin es una clase muy liviana que permite utilizar shapes sobre ellas, es decir, pintar lineas y rellenarlas.
La variable _timer se encargará de hacer una llamada a las funciones invalidateProperties, invalidateSize e invalidateDisplayList cada 50 milisegundos para que el cuadrado pintado se refresque visualmente y para que se le modifique su tamaño y propiedades.
La variable procesarBloque se definió para restringir los bloques de codigo que seran ejecutados cada vez que se llame al método commitproperties y updateDisplayList (ya que como estos métodos los vamos a llamar frecuentemente, es mejor que no se ejecute todo el codigo que ellos contienen constantemente.).
En el método create children debemos instanciar y agregar el ProgrammaticSkin que definimos ("bloque") al componente (para que pueda ser visualizado).
override protected function createChildren() : void
{
super.createChildren();
/*
Creo un ProgrammaticSkin y lo agrego a la lista de hijos del
componente.
*/
bloque = new ProgrammaticSkin();
this.addChild(bloque);
trace("createChildren");
}
En el método commitProperties se encargará de aumentar la propiedad "x" de la variable "bloque" para que el cuadradro que esta represente se mueva hacia la derecha.
override protected function commitProperties() : void
{
super.commitProperties();
trace("commitProperties");
/*
Debemos asegurarnos de que "bloque" este creado.
*/
if(bloque)
{
//Solo queremos aumentar la coordenada x de "bloque" si es menor a 100.
if(bloque.x<100) procesarBloque = true;
else procesarBloque = false;
/*
Esta condicional nos permite restringir los bloques que deseamos que sean procesados
esto se puede usar para mejorar el rendimiento del componente ya que de esta manera
podemos controlar la ejecucion de las porciones de codigo, no se debe ejecutar la
porcion que no sea necesaria.
*/
if(procesarBloque)
{
bloque.x++;
}
}
}
El metodo updateDisplayList se encargara de volver a pintar el cuadrado ahora que esta un podo mas a la derecha (porque commitProperties lo movio hacia la derecha.).
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
trace("updateDisplayList");
/*
En este punto pintamos nuestro bloque con el el ancho y alto de 200.
es importante dear de pintar a "bloque si no han ocurrido modificaciones de sus propiedads,para eso usamos la bandera "procesarBloque" que tambien la utilizamos en el commmitproperties
*/
if(procesarBloque)
{
//bloque.graphics.clear();
bloque.graphics.lineStyle(1,0x000000,1);
bloque.graphics.beginFill(Math.random() * 20000000, 1);
bloque.graphics.moveTo(unscaledWidth,unscaledHeight);
bloque.graphics.lineTo(unscaledWidth,0);
bloque.graphics.lineTo(0,0);
bloque.graphics.lineTo(0,unscaledHeight);
}
}
El metodo measure le da el tamaño inicial al componente.
override protected function measure() : void
{
super.measure();
trace("measure");
measuredWidth += 30;
measuredHeight += 30;
}
Luego de crear todos estos metodos debemos ejecutar la aplicacion en modo debugger (para que veamos lo que va arrojando la funcion trace).
Espero que les haya servido este tutorial, cualquier duda que tengan pueden escribirme al mail aalejo@gmail.com o dejar un comentario en la parte de abajo de esta página.
Ejemplo