Cómo construir un preloader propio

En este mi primer post en MadeInFlex voy a tratar un tema del que ya se han visto algunos ejemplos en los blogs de la comunidad Flex, el preloader o la precarga de las aplicaciones Flex.

En la mayoría de las aplicaciones que vamos a realizar, el cliente nos va a pedir traducir el mensaje del preloader o mejor aún, que lo personalizemos con la imagen de su empresa.

A parte de poner un ejemplo, y mejor que explicar paso a paso lo que hace, he considerado mejor hacer una traducción de la parte del manual de Adobe que hace referencia a este tema, pienso que explica bastante bien cual es el proceso a seguir.

Aquí teneis la traducción del capítulo correspondiente del manual de usuario de Adobe Flex.

Desde aquí podeis ejecutar el ejemplo. Puesto que cuando lo ejecutas el SWF es caheado por el navegador, para volver a verlo correctamente es conveniente vaciar la caché.

Desde aquí podeis descargar el archivo comprimido del ejemplo.

En el ejemplo he hecho una subclase de DownloadProgressBar, esta clase se la asigno a la propiedad preloader del contenedor Application. He insertado cuatro imágenes embebidas que pesan lo suficiente como para ver correctamente la barra de progreso.

[ftf w="450" h="200"]

xmlns:mx="http://www.adobe.com/2006/mxml"
preloader="clases.subclassOfDownloadProgressBar">








[/ftf]

He fabricado una subclase de MovieClip para pintar un simple rectángulo con el progreso de la carga, así como el texto que indica el porcentaje cargado. Esta es la clase “subclassOfMovieClip”:

[ftf w="450" h="200"]
package clases
{
import flash.display.MovieClip;
import flash.display.Shape;
import flash.text.TextField;
import mx.controls.Image;
import flash.display.Loader;
import flash.utils.ByteArray;
public class subclassOfMovieClip extends MovieClip{

[ Embed(source="madein_logo.jpg", mimeType="application/octet-stream") ]
public var WelcomeScreenGraphic:Class;

private var img:Loader;

private var info:TextField;
private var infop:TextField;
private var pBar:Shape;

public var pBarWidth:Number=300;
public var pBarHeight:Number=15;

public function subclassOfMovieClip(){
this.visible=false;
// Cargar la imagen que queremos mostrar
img=new Loader();
img.loadBytes( new WelcomeScreenGraphic() as ByteArray );
// Dibujar todos los elementos
this.drawGraphics();
}
public function drawGraphics():void{

addChild(img); // Añadir la imagen

info=new TextField();
info.width=pBarWidth;
addChild(info); // Añadir el texto

infop=new TextField();
infop.width=pBarWidth;
addChild(infop); // Añadir el texto para mostrar el porcentaje

pBar = new Shape();
pBar.graphics.beginFill(0x0000FF);
pBar.graphics.drawRect(0, 0, pBarWidth, pBarHeight);
pBar.graphics.endFill();
addChild(pBar); // Añadir la barra de progreso
}
public function moveGraphics():void {
// Ubicar todos los elementos en la pantalla
info.x=infop.x=pBar.x=this.stage.stageWidth /2 – pBarWidth /2;
pBar.y=this.stage.stageHeight /2 – pBarHeight /2;
info.y=pBar.y-pBarHeight-3;
infop.y=pBar.y+pBarHeight+3;
img.x=this.stage.stageWidth /2 – img.width/2;
img.y=30;
}
public function showProgress(status:Number, bytesLoaded:uint=0, bytesTotal:uint=0):void{
this.visible=true;
this.moveGraphics(); // Si se redimensiona el navegador, los gráficos se siguen centrando en pantalla

switch(status){
case 0: // Descargando
info.text=’PRELOADER DEMO. cargando ‘+bytesLoaded+’ bytes de ‘+bytesTotal;
var p:Number=(bytesLoaded*100)/bytesTotal; // porcentaje cargado

infop.text=p.toFixed()+’ % cargado';

pBar.graphics.beginFill(0x00EA00);
pBar.graphics.drawRect(0, 0, (pBarWidth*p)/100 , pBarHeight);
pBar.graphics.endFill();
break;
case 1: // Descarga completada
info.text=’descarga completada';
break;
case 2: // Inicializando aplicación
info.text=’iniciando aplicación';
break;
case 3: // Aplicación inicializada
break;
}
}
}
}
[/ftf]

Esta es la clase “subclassOfDownloadProgressBar”, la que es asignada a la propiedad “preloader” de Application, notar que se crea una instancia a la clase “subclassOfMovieClip” y se añade (addChild) como hija de ésta.

[ftf w="450" h="200"]
package clases
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import mx.events.FlexEvent;
import mx.preloaders.DownloadProgressBar;

public class subclassOfDownloadProgressBar extends DownloadProgressBar {

public var smc:subclassOfMovieClip;

public function subclassOfDownloadProgressBar(){
super();
smc=new subclassOfMovieClip();
this.addChild(smc);
}

override public function set preloader(preloader:Sprite):void{
preloader.addEventListener( ProgressEvent.PROGRESS , SWFDownloadProgress );
preloader.addEventListener( Event.COMPLETE , SWFDownloadComplete );
preloader.addEventListener( FlexEvent.INIT_PROGRESS , FlexInitProgress );
preloader.addEventListener( FlexEvent.INIT_COMPLETE , FlexInitComplete );
}

// Descargando
private function SWFDownloadProgress( event:ProgressEvent ):void{
smc.showProgress(0,event.bytesLoaded, event.bytesTotal);
}
// Descarga completada
private function SWFDownloadComplete( event:Event ):void{
smc.showProgress(1);
}
// Inicializando aplicación
private function FlexInitProgress( event:Event ):void{
smc.showProgress(2);
}
// Aplicación inicializada
private function FlexInitComplete( event:Event ):void {
this.removeChild(smc);
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
[/ftf]

Una nota más: en todo este proceso podemos modificar el color de fondo, simplemente tenemos que modificar la propiedad “bgcolor” del cargador html de la aplicación.

Creo que el ejemplo es bastante simple y aclaratorio, ya no tenemos excusa para no hacer nuestros propios preloaders, solamente hay que echarle un poquito de imaginación. :sad:

Salu2
Raúl Díaz

17 Comentarios

  1. Edgar Rivera

    Muy buen artículo Raúl, es muy útil y además has traducido mucho contenido. Estos aportes a la comunidad si que merecen la pena.

    Un saludo

    Edgar Rivera

  2. Carlos Rovira

    Totalmente :smile:

    Creo que este post refleja uno de los principales motivos de abrir MIF a la comunidad.

    Enhorabuena Raúl!, espero que este sea el comienzo de una larga lista de entradas como esta :wink:

  3. Joan Garnet

    Alguna vez había pensado en que tenía que personalizar la barra de pregarga inicial, pero nunca me había puesto a ello.
    Después de ver este ejemplo ya no tengo excusa…
    Gracias ;)

  4. Alberto Albericio

    Enhorabuena Raúl!

    Una recomendación.. creo que el artículo quedaría redondo si activas la opción de View Source de la aplicación ejemplo.

    Es sólo un consejo :)

    Bienvenido a MIF!

    Alberto

  5. Omar Guevara

    Muy buen artículo, lo probé y funciona bien, pero tengo un pequeño problema, cuando coloco un Accordion con 3 pestañas, y dentro de cada uno de ellas cargo una imagen y texto, al ir a la segunda o tercera pestañas me sale el siguiente error

    TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.

    at clases::subclassOfMovieClip/moveGraphics()
    at clases::subclassOfMovieClip/showProgress()
    at clases::subclassOfDownloadProgressBar/::FlexInitProgress()
    at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.preloaders::Preloader/::appProgressHandler()
    at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()
    at mx.managers::LayoutManager/::doPhasedInstantiation()
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at mx.core::UIComponent/::callLaterDispatcher2()
    at mx.core::UIComponent/::callLaterDispatcher()

    Creo q es porque la clase de preloader se llama de nuevo al cargar la imagen y el texto, soy nuevo en este cuento, espero que me colaboren… Gracias…

  6. Raul Diaz

    Omar, por lo que cuentas estás utilizando componentes mx: como el mx:accordion en el preloader, mira la documentación, no se deben utilizar estos tipos de componentes en los preloaders.

  7. Omar Guevara

    Gracias por la pronta respuesta pero, yo utilice las dos clases para el preload, solo action script 3, nada de componentes mx, el error me sale después de cargar la aplicación en un accordion que tengo dentro de la aplicación, el preload lo hace bien, aquí dejo la url para q vean el error, el caso es que con algunos navegadores sale el error en otros no, tengo el Mozilla Firefox 2.0.0.12

    http://www.tree-technology.com/nueva/

    En la pestaña de nosotros esta el accordion al que me refiero, gracias por la ayuda…

  8. kamui

    como puedo agregar en el siguiente actionscript un mouse clock (convertir el mouse en reloj), cambiar el tiempo de carga en porcentaje y por ultimo modificar la figura del loading.

    package Code
    {
    import mx.preloaders.*;
    import flash.events.ProgressEvent;
    import flash.geom.Rectangle;
    import mx.graphics.RoundedRectangle;

    public class DownloadProgressBarSubClassMin extends DownloadProgressBar
    {
    public function DownloadProgressBarSubClassMin()
    {
    super();
    //labelRect.width = 500;
    // labelRect.width = 500;
    //labelRect.height = 200;
    // Set the download label.
    backgroundColor = 0X000000;
    downloadingLabel=” Locstatt by Marrder Omnimedia”
    // Set the initialization label.
    initializingLabel=” Locstatt by Marrder Omnimedia”
    // Set the minimum display time to 2 seconds.
    MINIMUM_DISPLAY_TIME=2000;

    }

    // Override to return true so progress bar appears
    // during initialization.
    override protected function showDisplayForInit(elapsedTime:int,count:int):Boolean {
    return true;
    }

    // Override to return true so progress bar appears during download.
    override protected function showDisplayForDownloading(elapsedTime:int, event:ProgressEvent):Boolean {
    return true;
    }
    override protected function get labelRect():Rectangle{
    return new Rectangle(0,0,200,20);
    }
    override protected function get borderRect():RoundedRectangle{
    return new RoundedRectangle(0,0,200,50,5);
    }
    }
    }

  9. Carlos

    Que tal amigo, quisiera saber, si tienes idea de porque el cargador que hice usando tus clases, inicia en aprox 500 kb, el swf pesa 1mb, pero el cargador aparece tarde.

    gracias =)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Acerca de Made In Flex

Made In Flex es una comunidad de desarrolladores de Apache Flex creada en 2006.

Apache Flex, anteriormente conocido como Adobe Flex, es un SDK (kit de desarrollo de software) para crear aplicaciones enriquecidas - multiplataforma basadas en Adobe Flash donado por Adobe a la fundación Apache in 2011 y promocionado a proyecto de primer nivel en Diciembre de 2012.

Actualmente estamos cambiando muchos aspectos del sitio web para ofrecer un sitio útil para toda la comunidad que tenga en cuenta las necesidades actuales.

Últimas Fotos

Instalador de Apache Flex

Entrar o Registrase