Internacionalização do Flutter com fácil localização

Tempo de leitura: 4 minutes

Como a localização de aplicativos é muito comum no desenvolvimento de aplicativos móveis, pensei em escrever sobre um dos meus plug-ins favoritos de flutter. A internacionalização de aplicativos é realmente rápida e fácil com o plug-in easy_localization. Especialmente com a atualização mais recente. Vou orientá-lo a criar uma página de aplicativo simples com a funcionalidade de alteração de idioma.

Para começar, adicione a dependência do plug-in ao seu arquivo pubspec.yaml e execute o comando packages get.

dependencies:   
  easy_localization: ^3.0.1

Eu usei a versão acima. Certifique-se sempre de ter a versão mais recente do plug-in. Importe o plugin para o seu arquivo dart.

import 'package:easy_localization/easy_localization.dart';

No método main adicione o seguinte código. Eu criei a pasta assets dentro da minha pasta raiz e criei a pasta locales com meus arquivos de tradução de idioma. (en-UK.json e es-SP.json). Forneça o caminho e as localidades suportadas corretamente ao salvá-los. E também adicione seus ativos de localização aos seus ativos pubspec.yaml.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(EasyLocalization(
    path: 'assets/locales',
    supportedLocales: [Locale('en', 'UK'), Locale('es', 'SP')],
    child: MyApp(),
  ));
}

Para executar o código no iOS, adicione as chaves de idioma ao arquivo info.plist.

<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>es</string>
</array>

Vamos ver como devemos adicionar o MaterialApp.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Localization Demo',
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      home: TranslationDemo(),
    );
  }
}

Agora seu aplicativo está pronto para alterar o idioma. Você pode criar a classe TranslationDemo como um widget stateful com os widgets que deseja e um design de IU preferido. Nos arquivos json do seu idioma, adicione as palavras que você precisa traduzir. Adicione quantos arquivos json desejar e adicione o idioma às localidades suportadas. As chaves que usei para minha demonstração são as seguintes.

en-UK.json

{
 "title" : "Title",
 "app_local_demo" : "Application localization example",
 "demo_details" : "This is a sample project to change the language with a drop down menu of languages"
}

es-SP.json

{
 "title" : "Título",
 "app_local_demo" : "Ejemplo de localización de aplicaciones",
 "demo_details" : "Este es un proyecto de ejemplo para cambiar el idioma con un menú desplegable de idiomas"
}

Para obter as palavras, basta importar o pacote e adicionar a chave conforme o exemplo abaixo.

'title'.tr()

Você pode criar seu próprio menu suspenso, botão de opção ou qualquer widget para alterar o idioma. Acabei de usar um menu suspenso com estilos personalizados. Você pode salvar o último idioma alterado para definir como padrão. Use a preferência compartilhada para isso.

String dropdownValue = 'English - UK';
String icon = "uk.png";
Container(
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Container(
        margin: EdgeInsets.symmetric(vertical: 40, horizontal: 20),
        child: Row(
          children: [
            Text(
              'title'.tr() + ":",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            Expanded(
                child: Container(
                  margin: EdgeInsets.only(left: 20),
                  child: Text(
                    'app_local_demo'.tr(),
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                )),
          ],
        ),
      ),
      Container(
        width: width,
        margin: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
        child: Row(
          children: [
            Text(
              'details'.tr() + ":",
              style: TextStyle(fontSize: 15),
            ),
            Expanded(
                child: Container(
                  margin: EdgeInsets.only(left: 20),
                  child: Text('demo_details'.tr(),
                      style: TextStyle(fontSize: 15)),
                ))
          ],
        ),
      ),
      Container(
        margin: EdgeInsets.only(top: 50),
        width: width,
        alignment: Alignment.center,
        child: Container(
          height: 40,
          padding: EdgeInsets.only(left: 5),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(3),
            border: Border.all(color: Colors.black, width: .9),
          ),
          child: Container(
              padding: EdgeInsets.only(left: 4, right: 4),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  DropdownButton<String>(
                    icon: Container(
                      padding: EdgeInsets.only(
                        left: 10,
                      ),
                      child: Image(
                        image: AssetImage("assets/images/icons/" + icon),
                      ),
                      height: 30,
                      width: 30,
                    ),
                    iconSize: 18,
                    elevation: 16,
                    value: dropdownValue,
                    style: TextStyle(color: Colors.black),
                    underline: Container(
                      padding: EdgeInsets.only(left: 4, right: 4),
                      color: Colors.transparent,
                    ),
                    onChanged: (String newValue) {
                      setState(() {
                        if (newValue == 'English - UK') {
                          this.setState(() {
                            dropdownValue = 'English - UK';
                            icon = "uk.png";
                            context.setLocale(Locale('en', 'UK'));
                          });
                        } else if (newValue == 'Spanish - ES') {
                          this.setState(() {
                            dropdownValue = 'Spanish - ES';
                            icon = "es.png";
                            context.setLocale(Locale('es', 'SP'));
                          });
                        }
                      });
                    },
                    items: <String>['English - UK', 'Spanish - ES']
                        .map<DropdownMenuItem<String>>((String value) {
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(
                          value,
                          style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w600,
                            color: Colors.black,
                          ),
                        ),
                      );
                    }).toList(),
                  ),
                  Container(
                    margin: EdgeInsets.only(left: 3),
                    child: Icon(
                      Icons.keyboard_arrow_down,
                      size: 18,
                    ),
                  )
                ],
              )),
        ),
      )
    ],
  ),
),

 

Eu adicionei as chaves dos meus arquivos json assim.

Container(
   margin: EdgeInsets.symmetric(vertical: 40, horizontal: 20),
   child: Row(
     children: [
       Text(
         'title'.tr() + ":",
         style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
       ),
       Expanded(
           child: Container(
             margin: EdgeInsets.only(left: 20),
         child: Text(
           'app_local_demo'.tr(),
           style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
         ),
       )),
     ],
   ),
 ),
 Container(
   width: width,
   margin: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
   child: Row(
     children: [
       Text(
         'details'.tr() + ":",
         style: TextStyle(fontSize: 15),
       ),
       Expanded(
           child: Container(
             margin: EdgeInsets.only(left: 20),
         child: Text('demo_details'.tr(),
             style: TextStyle(fontSize: 15)),
       ))
     ],
   ),
 ),

Isso é tudo!!! Execute o aplicativo, altere o idioma e veja. Como este é um exemplo simples, você pode encontrar mais informações sobre o pacote no seguinte link.

Você pode encontrar o código completo no seguinte link.

https://github.com/caneto/flutter_demo (Pasta: /lib/screens/localization/)