Translator In Flutter

Translator In Flutter :

The internationalization (i18n) library for Flutter.

  • If translations for your data in different languages and switch between them easily your flutter application.

Screenshot :

Translator In Flutter

localization Package :

constants.dart

class Constants
{
    static const String defaultLocalizedAssetsPath = 'assets/i18n';

    static const String pluralZero = '0';
    static const String pluralOne = '1';
    static const String pluralElse = 'else';

    static const String pluralValueArg = '{{value}}';
}

global.dart

import 'package:flutter/cupertino.dart';
import 'localization.dart';
import 'localization_provider.dart';
import 'localized_app.dart';

Locale localeFromString(String code, {bool languageCodeOnly = false})
{
	if (code.contains('_'))
	{
		var parts = code.split('_');

		return languageCodeOnly ? Locale(parts[0]) : Locale(parts[0], parts[1]);
	}
	else
	{
		return Locale(code);
	}
}

String translate(String key, {Map<String, dynamic> args})
{
	return Localization.instance.translate(key, args: args);
}

String translatePlural(String key, num value, {Map<String, dynamic> args})
{
	return Localization.instance.plural(key, value, args: args);
}

void changeLanguage(BuildContext context, String localeCode)
{
	if (localeCode != null)
	{
		LocalizedApp.of(context).delegate.changeLanguage(localeFromString(localeCode));

		LocalizationProvider.of(context).state.onLanguageChanged();
	}
}

localization.dart

import 'constants.dart';

class Localization
{
    Map<dynamic, dynamic> _translations;

    Localization._();

    static Localization _instance;
    static Localization get instance => _instance ?? (_instance = Localization._());

    static void load(Map<dynamic, dynamic> translations)
    {
        instance._translations = translations;
    }

    String translate(String key, {Map<String, dynamic> args})
    {
        var translation = _getTranslation(key, _translations);

        if (translation != null && args != null)
        {
            translation = _assignArguments(translation, args);
        }

        return translation ?? key;
    }

    String plural(String key, num value, {Map<String, dynamic> args})
    {
        var pluralKeyValue = _getPluralKeyValue(value);
        var translation = _getPluralTranslation(key, pluralKeyValue, _translations);

        if(translation != null)
        {
            translation = translation.replaceAll(Constants.pluralValueArg, value.toString());

            if (args != null)
            {
                translation = _assignArguments(translation, args);
            }
        }

        return translation ?? '$key.$pluralKeyValue';
    }

    String _getPluralKeyValue(num value)
    {
        switch(value)
        {
            case 0: return Constants.pluralZero;
            case 1: return Constants.pluralOne;
            default: return Constants.pluralElse;
        }
    }

    String _assignArguments(String value, Map<String, dynamic> args)
    {
        for(final key in args.keys)
        {
            value = value.replaceAll('{$key}', '${args[key]}');
        }

        return value;
    }

    String _getTranslation(String key, Map<String, dynamic> map)
    {
        List<String> keys = key.split('.');

        if (keys.length > 1)
        {
            var firstKey = keys.first;

            if(map.containsKey(firstKey) && map[firstKey] is! String)
            {
                return _getTranslation(key.substring(key.indexOf('.') + 1), map[firstKey]);
            }
        }

        return map[key];
    }

    String _getPluralTranslation(String key, String valueKey, Map<String, dynamic> map)
    {
        List<String> keys = key.split('.');

        if (keys.length > 1)
        {
            var firstKey = keys.first;

            if(map.containsKey(firstKey) && map[firstKey] is! String)
            {
                return _getPluralTranslation(key.substring(key.indexOf('.') + 1), valueKey, map[firstKey]);
            }
        }

        return map[key][valueKey];
    }
}

localization_configuration.dart

import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'global.dart';
import 'localization_file_service.dart';

class LocalizationConfiguration
{
    Map<Locale, String> _localizations;

    Map<Locale, String> get localizations => _localizations;

    final Locale fallbackLocale;

    final List<Locale> supportedLocales;

    LocalizationConfiguration._(this.fallbackLocale, this.supportedLocales);

    static Future<LocalizationConfiguration> create(String fallbackLanguage, List<String> supportedLanguages, {String basePath = Constants.defaultLocalizedAssetsPath}) async
    {
        var configuration = new LocalizationConfiguration._(localeFromString(fallbackLanguage), _generateSupportedLocales(supportedLanguages));

        _validateConfiguration(fallbackLanguage, supportedLanguages);

        var files = await LocalizationFileService.getLocalizedFiles(supportedLanguages, basePath);

        configuration._localizations = files.map((x,y) => _getLocalizedEntry(x, y));

        return configuration;
    }

    static void _validateConfiguration(String fallbackLanguage, List<String> supportedLanguages)
    {
        if(!supportedLanguages.contains(fallbackLanguage))
        {
            throw new Exception('The fallbackLanguage [$fallbackLanguage] must be present in the supportedLanguages list [${supportedLanguages.join(", ")}].');
        }
    }

    static List<Locale> _generateSupportedLocales(List<String> supportedLanguages)
    {
        return supportedLanguages.map((x) => localeFromString(x, languageCodeOnly: true)).toSet().toList();
    }

    static MapEntry<Locale, String> _getLocalizedEntry(String languageCode, String file)
    {
        Locale locale;

        if(languageCode.contains('_'))
        {
            var parts = languageCode.split('_');

            locale = new Locale(parts[0], parts[1]);
        }
        else
        {
            locale = new Locale(languageCode);
        }

        return MapEntry(locale, file);
    }
}

localization_delegate.dart

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'constants.dart';
import 'localization_file_service.dart';
import 'localization_configuration.dart';
import 'localization.dart';

class LocalizationDelegate extends LocalizationsDelegate<Localization>
{
    Locale _currentLocale;

    final LocalizationConfiguration configuration;

    Locale get currentLocale => _currentLocale;

    LocalizationDelegate._(this.configuration);

    Future changeLanguage(Locale newLocale) async
    {
        var locale = _findLocale(newLocale) ?? configuration.fallbackLocale;
        
        if(_currentLocale != locale)
        {
            var localizedContent = await _getLocalizedContent(locale);

            Localization.load(localizedContent);

            _currentLocale = locale;
        }
    }

    @override
    Future<Localization> load(Locale newLocale) async
    {
        if(currentLocale != newLocale)
        {
            await changeLanguage(newLocale);
        }

        return Localization.instance;
    }

    Future<Map<String, dynamic>> _getLocalizedContent(Locale locale) async
    {
        var file = configuration.localizations[locale];

        var content = await LocalizationFileService.getLocalizedContent(file);

        return json.decode(content);
    }

    Locale _findLocale(Locale locale)
    {
        var existing = configuration.localizations.keys.firstWhere((x) => x == locale, orElse: () => null);

        if(existing == null)
        {
            existing = configuration.localizations.keys.firstWhere((x) => x.languageCode == locale.languageCode, orElse: () => null);
        }

        return existing;
    }

    @override
    bool isSupported(Locale locale) => locale != null;

    @override
    bool shouldReload(LocalizationsDelegate<Localization> old) => true;

    static Future<LocalizationDelegate> create({@required String fallbackLanguage,
                                                @required List<String> supportedLanguages,
                                                String basePath = Constants.defaultLocalizedAssetsPath}) async
    {
        var configuration = await LocalizationConfiguration.create(fallbackLanguage, supportedLanguages, basePath: basePath);

        return new LocalizationDelegate._(configuration);
    }
}

localization_file_service.dart

import 'dart:convert';
import 'package:flutter/services.dart';

class LocalizationFileService
{
    static const String assetManifestFilename = 'AssetManifest.json';

    static Future<Map<String, String>> getLocalizedFiles(List<String> languages, String basePath) async
    {
        var localizedFiles = await _getAllLocalizedFiles(basePath);

        final files = new Map<String, String>();

        for(final language in languages.toSet())
        {
            var file = _findLocalizationFile(language, localizedFiles, basePath);

            files[language] = file;
        }

        return files;
    }

    static Future<String> getLocalizedContent(String file) async
    {
        return await rootBundle.loadString(file);
    }

    static Future<List<String>> _getAllLocalizedFiles(String basePath) async
    {
        final manifest = await rootBundle.loadString(assetManifestFilename);

        Map<String, dynamic> map = jsonDecode(manifest);

        var separator = basePath.endsWith('/') ? '' : '/';

        return map.keys.where((x) => x.startsWith('$basePath$separator')).toList();
    }

    static String _findLocalizationFile(String languageCode, List<String> localizedFiles, String basePath)
    {
        var file = _getFilepath(languageCode, basePath);

        if(!localizedFiles.contains(file))
        {
            if(languageCode.contains('_'))
            {
                file = _getFilepath(languageCode.split('_').first, basePath);
            }
        }

        if(file == null)
        {
            throw new Exception('The asset file for the language "$languageCode" was not found.');
        }

        return file;
    }

    static String _getFilepath(String languageCode, String basePath)
    {
        var separator = basePath.endsWith('/') ? '' : '/';

        return '$basePath$separator$languageCode.json';
    }
}

localization_provider.dart

import 'package:flutter/widgets.dart';
import 'localized_app_state.dart';

class LocalizationProvider extends InheritedWidget
{
    final LocalizedAppState state;

    final Widget child;

    LocalizationProvider({Key key, this.child, this.state}) : super(key: key, child: child);

    static LocalizationProvider of(BuildContext context) => (context.inheritFromWidgetOfExactType(LocalizationProvider) as LocalizationProvider);

    @override
    bool updateShouldNotify(LocalizationProvider oldWidget) => true;
}

localized_app.dart

import 'package:flutter/widgets.dart';
import 'localization_delegate.dart';
import 'localized_app_state.dart';

class LocalizedApp extends StatefulWidget
{
    final Widget child;

    final LocalizationDelegate delegate;

    LocalizedApp(this.delegate, this.child);

    LocalizedAppState createState() => LocalizedAppState();

    static LocalizedApp of(BuildContext context) => context.ancestorWidgetOfExactType(LocalizedApp);
}

localized_app_state.dart

import 'package:flutter/widgets.dart';
import 'localized_app.dart';
import 'localization_provider.dart';

class LocalizedAppState extends State<LocalizedApp>
{
    void onLanguageChanged() => setState(() {});

    @override
    Widget build(BuildContext context) => LocalizationProvider(state: this, child: widget.child);

}

assets Package :

-i18n Package :

en.json

{
	"app_bar": {
		"title": "Welcome to the home page"
	},
	"button": {
		"cancel": "Cancel",
		"change_language": "Change Language"
	},
	"language": {
		"name": {
			"en": "English",
			"es": "Spanish",
			"fa": "Persian"
		},
		"selected_message": "Currently selected language is {language}",
		"selection": {
			"message": "Please select a language from the list",
			"title": "Language Selection"
		}
	},
	"plural": {
		"demo": {
			"0": "Please start pushing the 'plus' button.",
			"1": "You have pushed the button one time.",
			"else": "You have pushed the button {{value}} times."
		}
	}
}

es.json

{
	"app_bar": {
		"title": "Bienvenido a la página de inicio"
	},
	"button": {
		"cancel": "Cancelar",
		"change_language": "Cambiar idioma"
	},
	"language": {
		"name": {
			"en": "Inglés",
			"es": "Español",
			"fa": "Persa"
		},
		"selected_message": "El idioma seleccionado actualmente es {language}",
		"selection": {
			"message": "Por favor seleccione un idioma de la lista",
			"title": "Selección de idioma"
		}
	},
	"plural": {
		"demo": {
			"0": "Por favor, comience a presionar el botón 'más'.",
			"1": "Has presionado el botón una vez.",
			"else": "Ha presionado el botón {{value}} veces."
		}
	}
}

fa.json

{
	"app_bar": {
		"title": "به صفحه اصلی خوش آمدید"
	},
	"button": {
		"cancel": "لغو",
		"change_language": "تغییر زبان"
	},
	"language": {
		"name": {
			"en": "انگلیسی",
			"es": "اسپانیایی",
			"fa": "فارسی"
		},
		"selected_message": "زبان انتخاب شده فعلی {language}",
		"selection": {
			"message": "لطفاً زبانی را از لیست انتخاب کنید",
			"title": "انتخاب زبان"
		}
	},
	"plural": {
		"demo": {
			"0": "لطفاً دکمه \"افزودن\" را فشار دهید.",
			"1": "شما یک بار دکمه را فشار داده اید.",
			"else": "دکمه {{value}} بار فشار آورده اید."
		}
	}
}

main.dart

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'localization/global.dart';
import 'localization/localization_delegate.dart';
import 'localization/localization_provider.dart';
import 'localization/localized_app.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  var delegate = await LocalizationDelegate.create(fallbackLanguage: 'en', supportedLanguages: ['en', 'es', 'fa']);
  runApp(LocalizedApp(delegate, MyApp()));
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    var localizationDelegate = LocalizedApp.of(context).delegate;

    return LocalizationProvider(
      state: LocalizationProvider.of(context).state,
      child: MaterialApp(
          title: 'Flutter Translate Demo',
          localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            localizationDelegate
          ],
          supportedLocales: localizationDelegate.configuration.supportedLocales,
          locale: localizationDelegate.currentLocale,
          theme: ThemeData(primarySwatch: Colors.blue),
          home: MyHomePage(),
          ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  int _counter = 0;

  void _decrementCounter() => setState(() => _counter--);

  void _incrementCounter() => setState(() => _counter++);

  @override
  Widget build(BuildContext context) {
    var localizationDelegate = LocalizedApp.of(context).delegate;

    return Scaffold(
      appBar: AppBar(
        title: Text(translate('app_bar.title')),
      ),
      body:  Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(translate('language.selected_message', args: {'language': translate('language.name.${localizationDelegate.currentLocale.languageCode}')})),
            Padding(
              padding: EdgeInsets.only(top: 25, bottom: 160),
              child: CupertinoButton.filled(
                child: Text(translate('button.change_language')),
                padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 36.0),
                onPressed: () => _onActionSheetPress(context),
                )
            ),

            Padding(padding: const EdgeInsets.only(bottom: 10),
                    child: Text(translatePlural('plural.demo', _counter))
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                IconButton(
                  icon: Icon(Icons.remove_circle),
                  iconSize: 48,
                  onPressed: _counter > 0 ? () => setState(() => _decrementCounter()) : null,
                  ),
                IconButton(
                  icon: Icon(Icons.add_circle),
                  color: Colors.blue,
                  iconSize: 48,
                  onPressed: () => setState(() => _incrementCounter()),
                  ),
              ],
            )

          ],
        ),
      ),
    );
  }

  void showDemoActionSheet({BuildContext context, Widget child}) {
    showCupertinoModalPopup<String>(
      context: context,
      builder: (BuildContext context) => child).then((String value)
      {
        changeLanguage(context, value);
      });
  }

  void _onActionSheetPress(BuildContext context) {
    showDemoActionSheet(
      context: context,
      child: CupertinoActionSheet(
        title: Text(translate('language.selection.title')),
        message: Text(translate('language.selection.message')),
        actions: <Widget>[
          CupertinoActionSheetAction(
            child: Text(translate('language.name.en')),
            onPressed: () => Navigator.pop(context, 'en'),
            ),
          CupertinoActionSheetAction(
            child: Text(translate('language.name.es')),
            onPressed: () => Navigator.pop(context, 'es_ES'),
            ),
          CupertinoActionSheetAction(
            child: Text(translate('language.name.fa')),
            onPressed: () => Navigator.pop(context, 'fa'),
            ),
        ],
        cancelButton: CupertinoActionSheetAction(
          child: Text(translate('button.cancel')),
          isDefaultAction: true,
          onPressed: () => Navigator.pop(context, null),
          ),
        ),
      );
  }
}

The flutter tutorial  is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application

For more information about Flutter. visit www.fluttertutorial.in