8

I would like to start putting all my constant strings (like labels etc.) into a place that can be translated at a later stage.

How is this handled in Flutter?

juliusspencer
  • 3,008
  • 3
  • 26
  • 30
  • What do you mean by "translated"? Into what? What are you trying to accomplish? – OhMad May 21 '17 at 10:08
  • I guess he means that for a same item, it can be displayed either in French / English / Spanish and so on – Alexi Coard May 21 '17 at 11:20
  • 1
    In the Android framework all strings are stored in a values/strings.xml file. These are referenced through a resource class which is automatically updated. This makes translating easy as the strings.xml can be translated and then dropped into a folder such as values-es (for Spanish). I'd like to know what the mechanism is for Flutter. – juliusspencer May 22 '17 at 00:49

2 Answers2

15
  1. Create a Localizations.dart file

  2. Add the following code to that file:


import 'dart:async';
import 'package:flutter/material.dart';

import 'package:flutter/foundation.dart' show SynchronousFuture;
class DemoLocalizations {
  DemoLocalizations(this.locale);
  final Locale locale;
  static DemoLocalizations of(BuildContext context) {
    return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
  }
  static Map<String, Map<String, String>> _localizedValues = {
    'en': {
      'title': 'App title',
      'googleLogin': 'Login with Google'
    },
    'es': {
      'title': 'Título de App',
      'googleLogin': 'Conectar con Google'
    },
  };
  String get title {
    return _localizedValues[locale.languageCode]['title'];
  }
  String get googleLogin {
    return _localizedValues[locale.languageCode]['googleLogin'];
  }
}
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
  const DemoLocalizationsDelegate();
  @override
  bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);

  @override
  Future<DemoLocalizations> load(Locale locale) {
    // Returning a SynchronousFuture here because an async "load" operation
    // isn't needed to produce an instance of DemoLocalizations.
    return new SynchronousFuture<DemoLocalizations>(new DemoLocalizations(locale));
  }
  @override
  bool shouldReload(DemoLocalizationsDelegate old) => false;
}

  1. Import Localizations.dart into the file where you use the strings.

  2. Add the delegate DemoLocalizationsDelegate in the MaterialApp

MaterialApp(
  localizationsDelegates: [
   MyLocalizationsDelegate(),
  ],
...
)
  1. Substitute new Text("App Title"), with new Text(DemoLocalizations.of(context).title),

For each new string you want to localize, you need to add the translated text to each language's map and then add the String get... line. It's a bit cumbersome but it does what you need it to.

This is a quick overview of one way of doing it. You can read more about it in the Flutter docs: https://flutter.io/tutorials/internationalization/

Loïc Sacré
  • 53
  • 1
  • 7
AlexL
  • 962
  • 1
  • 10
  • 13
  • 3
    This seems to only work when in the main.dart file for me. (or what ever you call yours where runApp is). When trying to use the DemoLocalizations.of(context).someFieldName elsewhere from another files it returns a getter called on null error. I'm pretty unclear as to why this is happen. I have an open question for this at https://stackoverflow.com/questions/49214934/how-do-i-pass-an-internationalization-object-to-child-widgets-in-flutter. – SeaFuzz Mar 11 '18 at 23:50
8

I asked on gitter and I got the following:

Translation/Internationalization isn't a feature we consider "done" yet. https://pub.dartlang.org/packages/intl works in Flutter. We have a bug tracking this more generally: flutter/flutter#393

More complete internationalization (i18n) and accessibility support are two of the big arcs of work ahead of Flutter in the coming months. Another example of i18n work we have planned, is completing Right-to-left (RTL) layouts for our provided Widgets (e.g. teaching the Material library's Scaffold to place the Drawer on the left when the locale is an RTL language). RTL Text support works today, but there are no widgets which are out-of-the-box RTL-layout aware at this moment.

juliusspencer
  • 3,008
  • 3
  • 26
  • 30