Dentro del paradigma de Desarrollo con Flex los componentes juegan un papel muy importante ya que promueven la reutilización del código en diferentes partes de nuestra aplicación, hasta ahora en los capítulos anteriores hemos trabajado con los componentes que vienen incluídos en el framework de Flex pero a partir de ahora vamos a comenzar a crear nuestros propios componentes personalizados.

Es muy recomendable que si no lo has hecho revises los capítulos anteriores de la guía para poder probar sin problema el código de los ejemplos:

Componentes en Línea

Es posible crear componentes directamente en MXML utilizando un código similar al siguiente:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
xmlns="*">
<fx:Declarations>
<fx:Component className="MiBoton">
<s:Button />
</fx:Component>
</fx:Declarations>
<MiBoton label="Click" />
</s:Application>

Recordemos que Flex es un framework escrito con ActionScript 3.0 y todos los componentes están definidos dentro de clases. Una clase dentro de la teoría de orientación a objetos es la descripción misma del objeto, en muchos libros y/o tutoriales se utiliza la palabra blueprint, que es quién le dice al objeto cómo tiene que verse y qué es lo que puede hacer.

Dentro del código anterior la etiqueta Compontent le indica a Flex la creación de una nueva clase y al asignarle la propiedad className el nombre MiBoton será el nombre de nuestra clase. Cabe indicar que una parte importante de las clases es que podemos heredar de ellas todas sus características. En nuestro código estamos heredando un nuevo componente de la clase Button, al heredar no tenemos que repetir toda la funcionalidad simplemente tenemos que escribir el código necesario que describe un componente diferente al Button original, en nuestro caso nuestro botón es diferente por el tamaño del texto.

La herencia es un recurso muy valioso para la reutilización de código dentro de los lenguajes orientados a objetos, algo importante a hacer notar es que no es necesario el código fuente de una clase base de un componente para heredar del mismo.

Espacios de Nombre

Otro recurso interesante dentro de Flex se da con el lenguaje MXML cuando aprovechamos los espacios de nombre, los cuáles son un mecanismo para prevenir coalisiones entre nombres idénticos. Por decirlo de una manera si tenemos un componente llamado Boton en un espacio de nombre A y otro componente llamado Boton en un espacio de nombre B no habrá ningún conflicto puesto que cada uno se encuentra en su respectivo espacio de nombre.

Hasta ahora hemos hablado de forma muy básica sobre los espacios de nombre en el capítulo de Hola Mundo sin embargo es importante saber que cuando hacemos uso de componentes personalizados son parte de un concepto que debemos conocer. Un espacio de nombre puede ser declarado como un atributo de cualquier elemento pero en Flex es común hacerlo dentro del bloque Application. Un espacio de nombre comienza con xmlns (adivinaron de XML namespace!) seguido de un signo de “dos puntos” y el nombre que queremos utilizar para identificar a ese espacio de nombre. Siempre necesitamos al menos de un espacio de nombre que usualmente es fx, por ejemplo cuando usamos algún componente como Button es posible saber que nos referimos al botón estándar de Flex gracias a su espacio de nombre.

Como lo vemos en nuestro ejemplo de código podemos utilizar diferentes espacios de nombre dentro de una aplicación. Cuando encontramos un espacio de nombre de la siguiente forma xmlns=”*” quiere decir que cualquier clase que no este dentro de un paquete puede ser instanciada utilizando una etiqueta de MXML, si nuestra clase MiBoton estuviera definida dentro de un paquete maestros, entonces el xmlns debería de ser definido como xmlns=”maestros.*” es una práctica común entonces que los espacios de nombre que nosotros creamos tengan también asociado algún tipo de identificador, por ejemplo xmlns:mdw=”maestros.*” que nos permitiría utilizar un botón personalizado MiBoton de la siguiente manera:

<mdw:MiBoton label="Click" />

Cuando utilizamos el IDE de Flash Builder y creamos algún componente personalizado hay que notar que el namespace por defecto que le agrega a nuestros componentes es local y en algunas versiones anteriores se utilizaba de forma progresiva ns1, ns2, ns3, etc.

Componentes Externos

Los componentes en línea son útiles si solamente vamos a utilizar dichos compoenentes en un único archivo (situación poco común) así que dentro de un contexto más general para un componente es probable que lo utilicemos dentro de múltiples archivos, por lo que será más usable el definirlo dentro de un archivo independiente.

Para crear un componente personalizado desde Flash Builder solo hay que ir al menú File > New > MXML Component este comando va a crear un archivo nuevo donde estableceremos las siguientes propiedades:

Package: maestros
Name: MiBoton
Based on: spark.components.Button

Componente MXML de Flex

Al hacer esto Flash Builder va a crear un archivo cuyo código estará basado en Button en lugar de Application, lo vamos a modificar para que se vea como el código siguiente:

<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
fontSize="50" label="{etiqueta}">
<fx:Script>
[Bindable]
public var etiqueta:String;
</fx:Script>
</s:Button>

El nombre del archivo será MiBoton.mxml porque el nombre del componente es MiBoton. El paquete al que pertenece es maestros, de hecho podríamos ver al paquete como una carpeta dentro de nuestro directorio raíz de proyecto. A partir de este momento MiBoton esta disponible para todo el proyecto, no solamente dentro de un solo archivo. Otro punto importante a notar es la variable etiqueta que tiene un binding a la propiedad label del respectivo Button si quisieramos acceder a esa propiedad dentro de cualquier aplicación podríamos hacerlo de la siguiente manera:

<mdw:MiBoton etiqueta="Click" />

Esto vuelve muy flexible a los componentes ya que podemos generar componentes personalizados que a su vez tienen propiedades y métodos generados por nosotros mismos, la idea principal al crear componentes personalizados es pensar en un API para que otros desarrolladores o nosotros mismos podamos aprovechar dichos componentes.

Componentes de ActionScript 3.0

Hay muchas cosas que pueden realizarse con los componentes de MXML, sin embargo llega un punto donde necesitaremos ActionScript para completar nuestros objetivos. Crear un componente mediante ActionScript dentro de Flex también es muy sencillo, simplemente hay que crear una clase con el comando File > New > ActionScript Class y automáticamente la clase se convierte en un componente.

package maestros
{
	import spark.components.Button;
	public class MiBotonAS3 extends Button
	{
		public function MiBotonAS3()
		{
			super();
			this.label = "Maestros del Web";
		}
	}
}

La palabra package pone la clase dentro de la carpeta maestros y todo lo que esta dentro de llaves es parte del espacio de nombre, es importante notar la palabra public que indica un modificador de acceso que hará visible la clase hacia el exterior, lo mismo sucede con el método constructor que lleva el mismo nombre que la clase por convención, dentro del constructor encontraremos una llamada a un método super() que lo que hace es mandar llamar al contructor de la clase base para inicializar de forma correcta el componente. Dentro del mismo código encontraremos la palabra extends que indica la herencia a partir de la clase Button.

Para utiliza la clase dentro de nuestro archivo de MXML podemos hacerlo de la misma forma ya que un componente escrito en ActionScript es prácticamente lo mismo que uno escrito en MXML porque hay que recordar que el compilador traduce MXML hacia ActionScript.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mdw="maestros.*">
<mdw:MiBotonAS3 />
</s:Application>

Es una buena práctica cuando desarrollamos aplicaciones móviles el utilizar componentes de ActionScript 3.0 ya que logran mejor desempeño que los componentes basados en MXML.

Layout

Dentro de los diferentes tipos de componentes que podemos utilizar dentro de una aplicación Flex podemos aprovechar diferentes controles como botones, label, sliders, etc. pero para organizar dichos controles en una UI debemos de utilizar otro tipo de componentes llamados contenedores. Los contenedores principales son Application, Group y Panel, algunos de ellos inclusive tienen versiones optimizadas para dispositivos móviles. La clave para organizar nuestros controles es aprovechar la propiedad layout que indica el orden de aparición de los componentes internos.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:HorizontalLayout />
</s:layout>
<s:Button label="Botón 1" />
<s:Button label="Botón 2" />
<s:Button label="Botón 3" />
</s:Application>

En el código anterior aparecerán tres botones en la interfaz acomodados de forma horizontal, es posible utilizar otros valores para layout como vertical o tile e inclusive podemos crear nuestros propios layouts personalizados.

Tip de Experto

  • Cuando compilamos una aplicación Flex para PlayBook hay muchos detalles que debemos cuidar al momento de hacer el setup de nuestro ambiente de trabajo. Un pequeño tip que podría ahorrarles horas buscar en internet es conocer bien el descriptor de AIR (el archivo XMl asociado a cada aplicación) por ejemplo hay que modificar la propiedad versionNumber asignada por defecto a 1.0.0 para hacerlo compatible con el modelo de desarrollo para PlayBook.
  • De parte del equipo de Eduardo Pelegri (@pelegri) tenemos un blog llamado Open BB News dedicado a cubrir las noticias más importantes del mundo open source dentro de RIM y una de ellas es el desarrollo de ejemplos para AIR en github un recurso que vale mucho la pena.