Salve pessoal,
Hoje irei demonstrar como deixar sua aplicação multi-idiomas de uma maneira simples e facil.
Em grandes projetos web uma das principais preocupações dos arquitetos é a internacionalização do projeto. Fazer com que os usuários possam acessar e utilizar a aplicação sem ter que se preocupar com com a língua é um dos principais pontos positivos para um projeto se destacar no mercado.Visando isso os arquitetos da Adobe aperfeiçoaram o recurso de internacionalização do Flex 3, este recurso é chamado de ResourceBundle.
Desta maneira ficou muito simples e flexivel aplicar I18n veja porque:
1 - Você pode compilar recursos para várias localidades em uma única aplicação ou módulo.
2 - Você acessar todos os recursos através do ResourceManager, no qual pode gerenciar os recursos para várias localidades.
Você pode mudar em tempo de execução a localidade do recurso.
3 - Você também pode usar imagens, sons, etc, e não apenas Strings
Estes são apenas uns dos melhoramentos e vantagens de utilizar o ResourceBundle do Flex 3. O ResourceBundle possuim algumas exigências como criar um arquivo Locale para cada idioma, contudo existe uma forma de burlar isso utilizando arquivos properties.
Neste artigo irei demonstrar como aplicar I18n usando o ResourceManager sem ter criar arquivos Locales. I18n com ResourceBundle
Primeiramente iremos criar um projeto Flex, irei chama-lo de Flex_I18n_A. No projeto crie uma nova pasta chamada I18n nesta crie os seguintes arquivos XML: pt_BR, en_US e es_ES.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| <?xml version="1.0" encoding="iso-8859-1"?>
<locale lang="en_US">
<property key="titulo_app" value="Applying I18n in Flex applications" />
<property key="usuario" value="Username" />
<property key="senha" value="Password" />
<property key="login_erro" value="User credentials are wrong. Please try again" />
<property key="bt_login" value="Login" />
<property key="bt_logout" value="Logout" />
<property key="msg_boas_vindas" value="User logged in successfully." />
<property key="idioma" value="Language" />
<property key="selecione_idioma" value="Select a language." />
</locale>
<?xml version="1.0" encoding="iso-8859-1"?>
<locale lang="pt_BR">
<property key="titulo_app" value="Aplicando I18n em aplicações Flex." />
<property key="usuario" value="Usuário" />
<property key="senha" value="Senha" />
<property key="login_erro" value="Dados incorretos. Tente novamente." />
<property key="bt_login" value="Login" />
<property key="bt_logout" value="Sair" />
<property key="msg_boas_vindas" value="Usuário logado com sucesso." />
<property key="idioma" value="Idioma"/>
<property key="selecione_idioma" value="Selecione um idioma."/>
</locale>
<?xml version="1.0" encoding="iso-8859-1"?>
<locale lang="es_ES">
<property key="titulo_app" value="Aplicando i18n aplicaciones en Flex." />
<property key="usuario" value="Nombre de Usuario" />
<property key="senha" value="Contraseña" />
<property key="login_erro"
value="Credenciales de usuario se equivoca. Por favor, inténtelo de nuevo." />
<property key="bt_login" value="Inicio de sesión" />
<property key="bt_logout" value="Cerrar sesión" />
<property key="msg_boas_vindas" value="Usuario conectado correctamente." />
<property key="idioma" value="Idioma" />
<property key="selecione_idioma" value="Seleccione un idioma."/>
</locale> |
Agora com os três arquivos criados iremos criar a classe que irá fazer o carregamento dos arquivos xml.
Para cada key do XML será setado na propriedade content do ResourceBundle, desta maneira poderemos usar o metodo getString para pegar o value internacionalizado da key.
Agora iremos criar a classe com/flexI18n/utils/ConfigI18n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| package com.flexI18n.utils {
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import mx.resources.ResourceBundle;
import mx.resources.ResourceManager;
/**
* @author Fabiel Prestes
*/
public class ConfigI18n {
private var resourceBundle:ResourceBundle;
[Bindable]
public var currentLocale:String = "pt_BR";
public function ConfigI18n() {
super();
}
/**
* Carrega o xml locale baseado na String passada como parametro.
*/
public function loadLocale(locale:String= "pt_BR"):void {
currentLocale = locale;
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, createBundle);
xmlLoader.load(new URLRequest("I18n/" + currentLocale + ".xml"));
}
/**
* @private
* Apos o xml ser carregado com sucesso, deve-se pegar cada chave (key) e valor
* (value) e adicionar no resourceBundle, para assim ser acessado em qualquer local da aplicação.
* @eventType Event
*/
private function createBundle(e:Event):void {
var propertyList:XMLList = new XML(e.target.data).property;
resourceBundle = new ResourceBundle(currentLocale, "ApplicationResource");
for each (var property:XML in propertyList) {
resourceBundle.content[property.@key] = property.@value;
}
ResourceManager.getInstance().addResourceBundle(resourceBundle);
ResourceManager.getInstance().update();
ResourceManager.getInstance().localeChain = [currentLocale,"pt_BR"];
}
}
} |
Apenas uma observação na classe ConfigI18n, nós criamos uma variavel ResourceBundle aplicamos todas as mensagens internacionalizadas do XML e por final pegamos nosso resource e aplicamos no ResourceManager cujo este é um singleton, lembrando que sempre apos adicionar um novo resource deve-se fazer um update no ResourceManager para que todas as alterações sem efetivadas.
Outro detalhe é que quando XML terminou de ser carregado, foi instanciado o ResourceBundle e assim definido um nome para o Locale e um identificador para o BundleName. É através deste identicador que conceguiremos recurar as mensagens internacionalidas do ResourceManager.
OK, com a classe resposavel por carregar e configurar o ResourceBundle vamos criar uma tela de login para para demonstrar a autilização do ResourceBundle.
Agora iremos criar a classe com/flexI18n/views/LoginUI
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| <?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
import com.flexI18n.utils.ConfigI18n;
[Bindable] public var availableLocales:Array = [ {label:"English", data:"en_US"},
{label:"Portuguese", data:"pt_BR"},
{label:"Spanish", data:"es_ES"}
];
private function onLogin(e:Event):void {
PopUpManager.removePopUp(this);
Alert.show(resourceManager.getString('ApplicationResource','msg_boas_vindas'));
}
private function comboChangeHandler():void {
var locale:ConfigI18n = new ConfigI18n();
locale.loadLocale(localeComboBox.selectedItem.data);
this.localeComboBox.selectedIndex = -1;
}
]]>
</mx:Script>
<mx:Form width="100%">
<mx:FormItem label="{resourceManager.getString('ApplicationResource','usuario')}">
<mx:TextInput id="username" width="200"/>
</mx:FormItem>
<mx:FormItem label="{resourceManager.getString('ApplicationResource','senha')}" direction="horizontal">
<mx:TextInput id="password" displayAsPassword="true" width="200"/>
</mx:FormItem>
<mx:FormItem label="{resourceManager.getString('ApplicationResource','idioma')}">
<mx:ComboBox id="localeComboBox" selectedIndex="-1"
dataProvider="{availableLocales}"
change="comboChangeHandler()"
width="200" prompt="{resourceManager.getString('ApplicationResource','selecione_idioma')}"/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar width="100%" horizontalAlign="right">
<mx:Button label="{resourceManager.getString('ApplicationResource','bt_login')}"
click="onLogin(event)" enabled="{username.text != '' && password.text != ''}" x="517" y="118"/>
</mx:ControlBar>
</mx:TitleWindow> |
Se vocês olharem a classe acima, não foi em nenhum momento instanciado um objeto ResourceBundle, mais então de onde saiu
a variavel resourceBundle usada. Muito simples estamos usando o atributo da classe UIComponent.
A classe main fica da seguinte maneira.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import com.flexI18n.views.LoginUI;
import com.flexI18n.utils.ConfigI18n;
private function initApp():void{
new ConfigI18n().loadLocale();
var login:LoginUI = new LoginUI();
PopUpManager.addPopUp(login, this, true);
PopUpManager.centerPopUp(login);
}
]]>
</mx:Script>
</mx:Application> |
É isso aí, uma maneira simples e facil de fazer sua aplicação ficar multi-idioma.
Espero ter ajudado e até a próxima.