Veja nesta postagem como adicionar o recurso de multi idiomas as suas aplicações mobile desenvolvidas com Delphi 10 Seattle utilizando o componente TLang.
Com a alta do dólar desenvolver uma aplicação contando com o suporte a mais de um idioma passa a ser uma boa estratégia para os desenvolvedores que pretende lançar seus produtos em novos mercados.
Em abril de 2013, o MVP da Embarcadero Carlos Henrique Agnes, O Tatu, escrevia sobre suas impressões sobre uma das versões betas do RAD Studio na postagem: Delphi for iOS, nela Tatu abordava rapidamente o componente TLang, que ainda existe e acaba passando desapercebido pela maioria dos desenvolvedores Delphi.
TLang: um pouco sobre o componente
Presente no RAD Studio desde a versão XE2, o TLang é um componente não visual pertencente à biblioteca do FireMonkey, e não está acessível à VCL.
Nota 1 : FireMonkey - O FMX framework é a plataforma de desenvolvimento de aplicações e tempo de execução por trás do RAD Studio (Delphi e C++ Builder). FMX foi desenhada para equipes que estejam construindo aplicações multidispositivos verdadeiramente nativas para Windows, Mac, Android e iOS, levando-as a lojas de aplicações e corporações de modo acelerado.
Basicamente o TLang funciona fazendo a conversão de strings para outros idiomas previamente configurados no Language Designer.
Algumas propriedades do TLang merecem ser destacadas para um melhor entendimento e futura utilização, vamos a elas:
- Lang –> Utilizada para informar o idioma atualmente utilizado no TLang, consequentemente a ser passado para a aplicação.
- StoreInForm –> Informa se as definições aplicadas ao TLang serão armazenadas no formulário. Quando “false”, as definições deve ser carregadas através do método LoadFromFile.
- FileName –> Determina se o TLang deve selecionar automaticamente o valor a partir da lista de idiomas e aplicá-lo.
Criando nossa aplicação Multi Idiomas
Vamos iniciar o Delphi 10 Seattle e criar uma nova aplicação Multi Dispositivo, como já fizemos várias vezes em File->New->Muli Device Application – Delphi.
Em nosso formulário principal vamos atribuir alguns componentes: 3 Label, 2 Edit, 1 Memo, 3 Button e configurá-los como descrito abaixo:
- Label 1.Text -> ‘Idioma do Dispositivo’;
- Labe2.Text -> ‘Nome’;
- Label3.Text->‘Conteúdo do Memo’;
- Edit2.Text -> ‘Insira seu nome’;
- Button1.Text -> ‘Botão Erro’;
- Button2.Text -> ‘Português’;
- Button3.Text -> ‘Inglês’;
Lembre-se também de alterar em todos os Labels a propriedade AutoSize para True, isso fará com que o conteúdo da propriedade text não seja “cortado”.
Vou inserir também uma imagem, com a propriedade align setada como Botton e Wrap Mode como stretch, apenas para dar uma cara apresentável a nossa aplicação.
Adicionando o ingrediente Principal: TLang
Vamos inserir no nosso aplicação um TLang, na paleta Standard, para facilitar a compreensão vou alterar sua propriedade Name para Tradutor.
[Off]: Há poucos dias tive o desprazer de descobrir que havia um indivíduo copiando as minhas postagens aqui e publicando no seu site como se eu fosse um escritor de seu portal. Saiba quais "ramos" você vai seguir na sua vida, existem uns picaretas por aí.
Para garantir, vou inserir no formulário mais um Image agora com align Top e Wrap Mode também como Stretch. Com isso, a aparência de nossa aplicação será próxima à imagem abaixo:
Salve sua aplicação, no meu caso chamei o Form de frmPrincipal e sua Unit de frmPrincipalUnt, o Projeto salvei como MultiIdiomas.
Preparando o TLang: Language Designer
Selecione na tela o componente TLang, e no Object Inspector vá até sua propriedade Lang e clique sobre o botão “…”.
Isso fará com que seja aberto o Language Designer. Ele é a interface de configuração para inserirmos os idiomas no TLang. Note que ao abrir o Language Designer já carrega as strings que ele encontrou na aplicação, confira na imagem abaixo algumas considerações sobre o Language Designer:
Na prática lidar com o Language Designer é extremamente simples, vamos fazer isso a partir de agora.
Na caixa “two letter language code:” vamos inserir “BR”, em alusão a Brasil, poderia ser qualquer sequência de 2 letras, em seguida clicar sobre o botão Add, isso fará com que nosso idioma BR seja inserido no TLang nos possibilitando agora configurar os valores para cada uma das strings informadas no Language Designer. Veja que já preenchi alguns valores.
Assim sendo as strings da esquerda quando o idioma selecionado estiver em uso serão substituídas pelos seus respectivos valores à direita.
Agora que você já se familiarizou um pouco, vamos preparar a tradução de outras strings como o conteúdo do Edit2 e do Memo, este último passaremos em tempo de execução. Clique sobre o botão “+” ele abrirá espaço para digitarmos uma nova string a ser traduzida na caixa superior “New original text“, com isso vamos inserir o mesmo conteúdo que passamos anteriormente para a propriedade Text do Edit2: ” ‘Insira seu nome’ “, clique sobre o botão Add para confirmar a inclusão da string e altere o seu valor para tradução insira: “Seu nome de usuário“. Vamos repetir o procedimento criando um novo valor original: ” ‘Linha 1′ “ que será traduzido para “Observação 1“.
No caso do Idioma BR, ficamos com a seguinte configuração:
- Idioma do Dispositivo ->”Idioma do aparelho”
- Nome -> “Nome de Usuário”
- Conteúdo do Memo -> “Observação”
- Botão Erro ->”Gerar Exceção”
- Português -> “Português BR”
- Inglês -> “Inglês”
- ‘Insira seu nome’ -> “Seu nome de usuário”
- ‘Linha 1’ -> “Observação 1”
Agora vamos fazer o mesmo processo inserindo o idioma inglês, que será representado na caixa “two letter language code:” com a sequência “EN“.
Sua tradução para Inglês, “EN”, deve ficar como especificado abaixo:
- Idioma do Dispositivo ->”Device Language”
- Nome -> “User Name”
- Conteúdo do Memo -> “Observation”
- Botão Erro ->”Error Button”
- Português -> “Portuguese”
- Inglês -> “English”
- ‘Insira seu nome’ -> “Your user name”
- ‘Linha 1’ -> “Line 1”
Atenção: Repare que onde são strings passadas em componentes que não possuem a propriedade AutoTranslate, estas strings devem ser passadas entre aspas simples (' '). Para os demais casos, basta certificar-se de que o valor para AutoTranslate é true.
Trabalhoso, mas extremamente simples… vamos aos códigos!
Codificando a aplicação
Antes de tudo vamos inserir na cláusula uses da seção implementation as Units / Namesspaces necessárias para o funcionamento do código:
implementation {$R *.fmx} uses FMX.Platform, System.IOUtils;
A documentação do Delphi para o TLang recomenda que a mudança de idioma em tempo de execução não se dê através de TLang.Lang e sim através de TLang.LanStr[].
//Lang1.Lang := 'en'; // do not use this LoadLangFromStrings(Lang1.LangStr['en']); // use this instead
Então, partindo da documentação disposta na Embarcadero DocWiki para o TLang , o evento OnClick do Button2, “Português”, terá o seguinte código:
procedure TfrmPrincipal.Button2Click(Sender: TObject); begin LoadLangFromStrings(Tradutor.LangStr['BR']); end;
Já o evento OnClick do Button3, “Inglês”, seguindo a mesma linha será como abaixo:
procedure TfrmPrincipal.Button3Click(Sender: TObject); begin LoadLangFromStrings(Tradutor.LangStr['EN']); end;
Nota: LoadLangFromStrings está declarada Unit / Namespace FMX.Types, é importante notar que a função faz sua busca de forma CaseSensitive, ou seja, diferenciando maiúsculo e minúsculo.
Com isso nossa aplicação já está funcional… caso você a execute, clicando sobre cada um dos botões codificados, ela já será capaz de traduzir as strings em tela, pode testar aí se quiser, mas já adianto que vamos mais além…
Codificando para Tempo de Execução
Essa postagem já deveria ter sido publicada há tempos, mas nosso amigo Tatu, resolveu no mesmo dia que eu ia escrever fazer uma pergunta sobre o TLang que me deixou extremamente intrigado: Como seria a utilização do TLang em run time? E nas mensagens de Exceção, num bloco try exception, por exemplo?
Pois bem, após alguns testes cheguei ao seguinte… passando uma string, previamente configurada no Language Designer, em tempo de execução à função Translate() a mesma será traduzida pelo TLang. Assim sendo vamos exemplificar na codificação do Button1, “Botão Erro”, logo abaixo, passando a mensagem através da função Translate():
procedure TfrmPrincipal.Button1Click(Sender: TObject); begin raise Exception.Create(Translate('Erro do botão 1')); end;
Nota: Translate() retorna uma string especificada com sua tradução correspondente no idioma atual, quando não encontrada a própria string é retornada.
Vamos voltar ao Language Designer e inserir a string Original ” ‘Erro do Botão 1’ “, devendo neste caso, ser o valor passado entre aspas simples (‘ ‘), com a tradução “Button One Error“ para o idioma “EN”, e para o “BR” vamos traduzir como “Deu ruim 1“.
Por se tratar de conteúdo passado em uma mensagem e estarmos forçando a tradução, já que não há a propriedade AutoTranslate, devemos aqui também passar o valor original dentro de aspas simples (‘ ‘).
Ao final do projeto nosso Language Designer deve estar como nas imagens abaixo:
Execute a aplicação, clique sobre o botão 1 e altere o idioma e execute clique sobre o botão 1 novamente. Teoricamente a aplicação já está pronta… note porém que ao iniciarmos a mesma ela ainda “não sabe” qual idioma está sendo executado, para isso vamos agora capturar o idioma do dispositivo, aquele mesmo setado nas configurações.
Capturando o Idioma Configurado no Dispositivo Android
Mantendo a linha, embora todo o processo até aqui se aplique à plataforma FireMonkey, eu estou utilizando especificamente o Delphi Android, portanto daqui pra frente, os códigos descritos se aplicam ao desenvolvimento específico para dispositivos Android.
Vamos adicionar no evento OnActivate do formulário o seguinte código:
procedure TfrmPrincipal.FormActivate(Sender: TObject); var Local : IFMXLocaleService; begin if TPlatformServices.Current.SupportsPlatformService(IFMXLocaleService, Local) then begin // Atribuimos o Valor do ID do Idioma do Dispositvo ao TLang // Como o resultado é minúsculo, convertemos para maiúsculo, como usuado // nos idiomas em nosso TLang Tradutor.Lang := UpperCase(Local.GetCurrentLangID); end; //Veja que o valor do Edit1 agora contém o idioma retornado do Dispositivo Edit1.Text := Local.GetCurrentLangID; if Tradutor.Lang = 'PO' then // Quando o idioma for Português no dispositivo vamos usar o BR de nosso TLang LoadLangFromStrings(Tradutor.LangStr['BR']); //Forçamos a tradução do conteúdo do Edit2 Edit2.Text := Translate(Edit2.Text); Memo1.Lines.Clear; //Forçamos a tradução do conteúdo do Memo Memo1.Lines.Add(Translate('Linha 1')); end;
Resultado final
Este é resultado final do projeto…
Confira esse vídeo que fiz demonstrando o funcionamento da aplicação:
É isso, embora pareça mais longo e complexo é muito simples… você pode forçar sempre a passagem das strings utilizando a função Translate(), isso vai garantir o funcionamento da aplicação nos idiomas que você configurou no TLang.
Espero que seja útil, até a próxima!