É muito comum hoje em aplicações Flex/Air a necessidade de transpor informações entre a app e usuário. Grande parte dos usuários não fica satisfeita quando, ao realizar alguma tarefa, o sistema exibe uma caixa com texto e uns botões na parte central da aplicação. Há alguns fatores importantes que devem ser levados em consideração:
- Usuários não têm o costume de ler toda a informação contida em alertas.
- O usuário não quer ter seu fluxo de trabalho interrompido por um alerta, que na grande parte do tempo ele não quer ler.
- Fica difícil, em primeira instância visual, o usuário distinguir se o alerta é um erro ou apenas mensagens de rotina como “salvo com sucesso”.
Se pararmos para pensar melhor, poderemos encontrar outros fatores importantes.
Uma solução elegante para este problema é a criação de um componente que possa passar a mensagem ao usuário de uma forma que não impeça o fluxo de trabalho e, ao mesmo tempo, chame a atenção para a informação que o sistema esteja passando.
Para este propósito vamos um componente de mensagem similar ao que o msn e alguns clientes de twitter, entre outros aplicativos, utilizam.
Requisitos para o desenvolvimento do artigo:
- Ter Flex/Flash Builder ou outra IDE.
- Ter SDk 3 ou superior.
- Conhecimento em ActionScript e Mxml.
Nivel de dificuldade: 5
Certo, agora vamos ao que realmente interessa.
Passo 1
Criar um projeto flex com o nome “AlertaCustomizado” ou outro qualquer e com a seguinte estrutura:

Passo 2
Criar a classe AlertaUI.as. Esta é a classe que será exibida para o usuário, ou seja, será o componente principal. Esta classe é relativamente simples, composta pelos seguintes componentes nativos do flex:
1. O componente base será um Canvas;
2. Teremos dois efeitos Parallel:
- createEffect = responsável por exibir o componente alerta na tela, este será composto pelos efeitos Move e Fade;
- removeEffect = responsável por ocultar o componente de alerta da tela pai, este também será composto por dois efeitos, o Move e o Fade. Poderíamos ter utilizado nos dois casos – tanto no create quanto no remove o efeito Move, contudo para dar um pouco mais de elegância utilizaremos o fade;
3. Um componente Label, que será definido como o título do nosso alerta.
4. Um componente Text, que terá o conteúdo do alerta que desejamos apresentar ao usuário.
5. Um componente Image, para ser exibido ao lado do título do alerta.
Segue a baixo o código da classe AlertaUI.mxml. Ele é relativamente simples, o único detalhe é a vinculação dos efeitos createEffect e removeEffect aos respectivos eventos do canvas.
<?xml version="1.0" encoding="utf-8"?><br /><mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="200" height="100"<br /> styleName="fundoAlertaSucesso" paddingBottom="5" paddingLeft="5" paddingTop="5" paddingRight="5"<br /> verticalScrollPolicy="off" horizontalScrollPolicy="off"<br /> creationCompleteEffect="{createEffect}" removedEffect="{removeEffect}"><br /><br /> <mx:Style><br /> .fundoAlertaSucesso{<br /> borderStyle: applicationControlBar;<br /> fill-colors: #03A438, #6FCE8F;<br /> fillAlphas: 1, 1;<br /> highlightAlphas: 0, 0;<br /> drop-shadow-enabled: true;<br /> corner-radius: 5;<br /> }<br /><br /> .fundoAlertaErro{<br /> borderStyle: applicationControlBar;<br /> fill-colors: #E43434, #FCA5A5;<br /> fillAlphas: 1, 1;<br /> highlightAlphas: 0, 0;<br /> drop-shadow-enabled: true;<br /> corner-radius: 5;<br /> }<br /> </mx:Style><br /><br /> <mx:Script><br /> <![CDATA[<br /> [Bindable]<br /> protected var _titulo:String;<br /><br /> [Bindable]<br /> protected var _conteudo:String;<br /><br /> [Bindable]<br /> protected var _icone:String;<br /> ]]><br /> </mx:Script><br /><br /> <!-- Criando e configurando os efeitos --><br /> <mx:Parallel id="createEffect" duration="700"><br /> <mx:Move id="mvExibirAlerta"/><br /> <mx:Fade/><br /> </mx:Parallel><br /><br /> <mx:Parallel id="removeEffect" duration="700"><br /> <mx:Move id="mvOcultarAlerta"/><br /> <mx:Fade/><br /> </mx:Parallel><br /><br /> <mx:Label id="lbTitulo" width="100%" text="{_titulo}" fontFamily="Courier New" fontSize="14"<br /> fontWeight="bold" color="#FFFFFF" left="5" top="5"/><br /><br /> <mx:Text id="tConteudo" htmlText="{_conteudo}" fontFamily="Courier New" fontSize="12" left="5"<br /> top="30" right="5" bottom="5"/><br /><br /> <mx:Image width="20" height="20" right="5" top="5" id="imgIcon" source="{_icone}" visible="{_icone != null}"/><br /><br /></mx:Canvas>Passo 3
Com o esqueleto do nosso alerta pronto, agora iremos definir as funcionalidades para ele. Para isso, vamos criar uma classe que estenda AlertaUI.mxml. Esta classe, sim, pode parecer complexa, mas é muito simples. Requer apenas um pouco de atenção para alguns detalhes, vamos a eles:
1. Método show – tem o mesmo intuito do método Alert.show, ou seja, exibir o componente na tela. Pode receber até 5 parâmetros:
- Título = Define o título que será exibido no componente.
- Conteúdo = Define o conteúdo que será exibido dentro do componente Text.
- TipoAlerta = irá definir qual o style que será utilizado no Alerta. Digamos que você queira que, quando ocorrer um erro na aplicação, seja exibido um alerta com um estilo diferente para chamar a atenção do usuário, ou que quando ocorra algo rotineiro, como “cadastro salvo com sucesso” etc., seja exibido um alerta também com um estilo diferente. Nessa situação, esse parâmetro é de suma importância, pois aqui você poderá criar diferentes Style.css e defini-los da forma que bem entender. Neste artigo, para exemplo didático, irei criar apenas dois Style, um identificando ERRO e outro SUCESSO.
- Duração = Define o tempo, em segundos, que o alerta ficará disponível para o usuário, o padrão será 3s.
- Ícone = Define um ícone a ser mostrado ao lado do título.
Assim, o método show terá as seguintes responsabilidades:
- instanciar uma nova variável Alerta;
- configurar o alerta criado baseado nos argumentos passados, como: Título, Ìcone, tipo do style etc.;
- executar o método PopUpManager.addPopUp passando como parâmetro o alerta criado;
- e, por último e muito importante: avisar ao Gerenciador de Alerta (falarei disso em breve) que foi criado um novo alerta e ele está sendo exibido na tela.
2. Método onCreate: é o segundo método mais importante do componente. O onCreate está vinculado ao CREATION_COMPLETE; assim, quando todos os componentes do alerta forem criados, ele terminará de realizar algumas configurações que somente são possíveis nesse estágio. São elas:
- definir o X e o Y do alerta, ou seja, definir onde o alerta será exibido na tela. Para efeito didático, irei abordar a mesmo localização do MSN, no canto inferior direito, mas esta é uma funcionalidade que você poderá, futuramente, customizar para ser exibida em outros locais;
- configurar o efeito Move do createEffetc. Assim, se já estiver sendo exibido um alerta na tela, deverá ser levado em consideração a posição Y do novo alerta para que ele não fique sobreposto ao antigo. Precisamos apenas configurar o yFrom e o yTo;
- configurar o efeito Move do removeEffetc para indicar o yTo do mesmo, com ele definirei sempre o Y da altura do Application;
- Serão adicionados dois listeners: MouseEvent.ROLL_OVER e MouseEvent.ROLL_OVER. Neles estará a jogada do alerta. Será bem comum o sistema exibir um alerta e o usuário não conseguir ler todo o seu conteúdo, ou até mesmo fechá-lo. Para resolver este problema, iremos fazer com que quando o usuário colocar o mouse em cima do alerta, ele não será ocultado, mesmo que o tempo de 3 segundos seja atingido, e que quando o usuário remover o mouse do alerta, ele será ocultado imediatamente;
- criar e configurando um timer para o Alerta. Isso vai marcar quando o alerta deverá ser ocultado.
3. Método fecharAlerta: apenas remove da tela o alerta e avisa isso ao gerenciador de alerta.
Segue o código do Alerta.as
package com.fabielprestes.views.impl {<br /> import com.fabielprestes.views.AlertaUI;<br /><br /> import flash.display.DisplayObject;<br /> import flash.events.MouseEvent;<br /> import flash.events.TimerEvent;<br /> import flash.utils.Timer;<br /><br /> import mx.core.Application;<br /> import mx.events.FlexEvent;<br /> import mx.managers.PopUpManager;<br /><br /><br /> /**<br /> * Responsavel por exibir e controlar o componente de alerta na tela.<br /> *<br /> * @author Fabiel Prestes<br /> */<br /> public class Alerta extends AlertaUI {<br /><br /> private var _novaAltura:int;<br /><br /> private var _duracao:int = 3000;<br /><br /> private var _timerOcultarAlerta:Timer;<br /><br /> public static var ALERTA_SUCESSO:int = 0;<br /> public static var ALERTA_ERRO:int = 1;<br /><br /> public function Alerta() {<br /> super();<br /><br /> this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreate);<br /> }<br /><br /> /**<br /> * @private<br /> * Espera o alerta ser totalmente criado para seguir o fluxo de configuraçao de posicionamento.<br /> * @param evt<br /> */<br /> private function onCreate(evt:FlexEvent):void {<br /><br /> /* Definindo o local onde o alerta será exibido,<br /> * Por simplicidade irei adotar o mesmo padrao do MSN, Twitter e outros, ou seja,<br /> * no canto inferior direito da tela<br /> *<br /> * Define o X, para isso pega-se o tamanho total da tela - o tamanho do nosso alerta - um gap qualquer.<br /> * Define o Y, para isso pega-se a (altura total da tela - um gap qualquer) - (a altura do nosso alerta * total de alerta visiveis na tela) */<br /> this.x = Application.application.width - this.width - 5;<br /> this.y = (Application.application.height - 5) - (this.height * GerenciadorAlerta.getInstance().totalAlertaVisivel);<br /><br /> /* Configurando os efeitos de MOVE. */<br /> this.mvExibirAlerta.yFrom = Application.application.height;<br /> this.mvExibirAlerta.yTo = y;<br /><br /> this.mvOcultarAlerta.yTo = Application.application.height;<br /><br /> /* Configurando o eventos do MOUSE<br /> *<br /> * Apos o alerta ser exibido o mesmo ficará visivel apenas por um determinado tempo.<br /> * Desta maneira caso o demore para ler a msg o alerta será ocultado, para que isso nao aconteça<br /> * iremos definir que quando o usuario colocar o mouse em cima o alerta o mesmo fica disponivel ate<br /> * que o usuario retire o mouse de cima do alerta. */<br /> this.addEventListener(MouseEvent.ROLL_OVER, function():void {<br /> _timerOcultarAlerta.removeEventListener(TimerEvent.TIMER_COMPLETE, fecharAlerta);<br /> });<br /><br /> this.addEventListener(MouseEvent.ROLL_OUT, function():void {<br /> fecharAlerta(null);<br /> });<br /><br /> /* Configurando o Tempo 'Timer' no qual o alerta ficará disponivel antes de ser ocultado */<br /> _timerOcultarAlerta = new Timer(_duracao, 1);<br /> _timerOcultarAlerta.addEventListener(TimerEvent.TIMER_COMPLETE, fecharAlerta);<br /> _timerOcultarAlerta.start();<br /><br /> /* Ao sair deste metodo o efeito Parallel que nos deixamos como Bindable no creationCompleteEffect da Tela<br /> * será ativado */<br /> }<br /><br /> /**<br /> * @private<br /> * Remove o alerta da Tela.<br /> * Neste momento o efeito Parallel que nos deixamos como Bindable no removedEffect da Tela<br /> * será ativado<br /> * @param evt<br /> */<br /> private function fecharAlerta(evt:TimerEvent):void{<br /> PopUpManager.removePopUp( this );<br /><br /> /* Avisa o gerenciador que foi removido um Alerta */<br /> GerenciadorAlerta.getInstance().alertaRemovido();<br /> }<br /><br /> /**<br /> * Responsavel por criar, configurar e exibir o Alerta tendo como base os argumentos como referencia.<br /> *<br /> * @param titulo Define o titulo a ser exibido no componente<br /> * @param conteudo Define o conteudo do alerta<br /> * @param tipoAlerta Define o style do alerta<br /> * @param duracao Define a duracao em segundos que o alerta ficará visivel para o usuario. Padra 3000 '3s'<br /> * @param icone Define um icone para ser exibido no alerta<br /> * @return a instancia do alerta criado e exibido;<br /> */<br /> public static function show(titulo:String, conteudo:String, tipoAlerta:int = 0, duracao:int = 3000, icone:String = null):Alerta {<br /> var alerta:Alerta = new Alerta();<br /> alerta._titulo = titulo;<br /> alerta._conteudo = conteudo;<br /> alerta._icone = icone;<br /> alerta._duracao = duracao;<br /><br /> /* Define o Style do Alerta pelo tipo.<br /> * O padrao será sempre o fundoAlertaSucesso */ <br /> if(tipoAlerta == ALERTA_ERRO)<br /> alerta.setStyle('styleName', 'fundoAlertaErro');<br /><br /> /* Exibe o alerta na tela */<br /> PopUpManager.addPopUp(alerta, DisplayObject(Application.application), false);<br /><br /> /* Avisa o gerenciador que foi criado um novo alerta */<br /> GerenciadorAlerta.getInstance().alertaCriado();<br /><br /> return alerta;<br /> }<br /> }<br />}Passo 4
Criando o Gerenciador de Alertas. Ele tem a finalidade de armazenar todos os alertas que estão sendo exibidos no momento. Isso deve ser feito para que quando o método onCreate for configurar os eventos, ele calcule exatamente a posição onde o novo alerta será exibido. O gerenciador será um Singletom para estas informações estarem visíveis e únicas para toda a aplicação.
Segue o código GerenciadorAlerta.as
<br />package com.fabielprestes.views.impl {<br /><br /> /**<br /> * Classe responsavel por gerenciar os alertas que estao visiveis ao usuario.<br /> * Esta classe será um Singleton.<br /> *<br /> * @author Fabiel Prestes<br /> */<br /> public class GerenciadorAlerta {<br /><br /> private static var _instance:GerenciadorAlerta;<br /><br /> private var _totalAlertaVisivel:int = 0;<br /><br /> private var _totalAlertaVisivelAux:int = 0;<br /><br /> public function GerenciadorAlerta(type:PrivateGerenciadorAlerta) {<br /> if (type == null) {<br /> throw new Error("Erro: Não é possivel instancia GerenciadorAlerta, já que este é um Singleton.");<br /> }<br /> }<br /><br /> /**<br /> * Retorna a instancia unica da classe GerenciadorAlerta<br /> */<br /> public static function getInstance():GerenciadorAlerta {<br /> if (_instance == null)<br /> _instance = new GerenciadorAlerta(new PrivateGerenciadorAlerta());<br /> return _instance;<br /> }<br /><br /> public function alertaCriado():void {<br /> _totalAlertaVisivel++;<br /> _totalAlertaVisivelAux++;<br /> }<br /><br /> public function alertaRemovido():void {<br /> _totalAlertaVisivel--;<br /><br /> if(_totalAlertaVisivel <= 0)<br /> _totalAlertaVisivelAux = 0;<br /> }<br /><br /> /**<br /> * Retorna o total de alerta que esta visivel para o usuario na tela<br /> */<br /> public function get totalAlertaVisivel():int {<br /> return _totalAlertaVisivelAux;<br /> }<br /> }<br />}<br /><br />internal class PrivateGerenciadorAlerta {<br /> public function PrivateGerenciadorAlerta() {<br /> }<br />}Passo 5
É o último. Criaremos uma classe teste que vai exibir quatro tipos de alerta: de sucesso com e sem imagem, e de erro com e sem imagem.
<?xml version="1.0" encoding="utf-8"?><br /><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"><br /> <mx:Script><br /> <![CDATA[<br /> import com.fabielprestes.views.impl.Alerta;<br /><br /> ]]><br /> </mx:Script><br /><br /> <mx:Button click="Alerta.show('Teste Sucesso', 'Conteudo teste')" label="Alerta Sucesso"/><br /> <mx:Button click="Alerta.show('Teste Sucesso', 'Conteudo teste', Alerta.ALERTA_SUCESSO, 3000, 'assets/user.gif')" label="Alerta Sucesso Com Imagem"/><br /> <mx:Button click="Alerta.show('Teste Erro', 'Conteudo teste', Alerta.ALERTA_ERRO)" label="Alerta Erro"/><br /> <mx:Button click="Alerta.show('Teste Erro', 'Conteudo teste', Alerta.ALERTA_ERRO, 3000, 'assets/user.gif')" label="Alerta Erro Com Imagem"/><br /></mx:Application>É isso aí, pessoal! Uma maneira simples e fácil de se criar alertas. Agora é só você customizar da melhor maneira. Este componente é bem parecido com o Notification e Gragle.
Qualquer dúvida ou sugestão, é só deixar nos comentários ou mandar um email.
Arquivos







